Python3爬取豆瓣电影保存到MySQL数据库
首页 / 频道 / 显示主题:Python3爬取豆瓣电影保存到MySQL数据库

Python3爬取豆瓣电影保存到MySQL数据库


时间:2017年12月06日 13:15:00点击:1502类别:技术开发

http://www.jianshu.com/p/dcba92805771

代码基于python3,用到的类库有:

requests:通过伪造请求头或设置代理等方式获取页面内容,参考文档
BeautifulSoup:对页面进行解析,提取数据,参考文档
PyMySQL:python3版本中用于操作MySQL数据库,python2中则使用mysqldbGithub

pip安装用到的几个类库:

pip install requests
pip install bs4
pip install pymysql

分析豆瓣电影页面


页面分析:
爬取数据之前,我们都需要对页面进行分析,看我们可以从中提取到哪些数据,从下图我们看到豆瓣电影top250的页面结构,我们可以从中提取出排行榜(rank)、电影名字(name)、电影详情页链接(link)、电影海报(poster)、电影评分(score)、电影评论(quote)等,我在图中进行了标注

URL分析:
通过点击分页我们可以发现URL的格式为:https://movie.douban.com/top250?start=num&filter=
其中num表示25的倍数的数字,最小是0也就是第一页,最大为225也就是最后一页,这可以作为我们爬取页面的限制条件,filter为过滤条件这里可不用管

 

代码


引入类库:

 
import pymysql
import requests
from bs4 import BeautifulSoup

定义爬取链接,%d用作数字占位:

baseUrl = "https://movie.douban.com/top250?start=%d&filter="
定义爬取数据方法:
def get_movies(start):
url = baseUrl % start # 拼接爬取链接
lists = [] # 存储此页面的电影数据
html = requests.get(url) # requests请求页面内容,由于豆瓣没有限制爬取,所以不用设置伪请求头
soup = BeautifulSoup(html.content, "html.parser") # BeautifulSoup解析页面内容
items = soup.find("ol", "grid_view").find_all("li") # 获取所有的电影内容
for i in items:
movie = {} # 临时存取电影的数据
movie["rank"] = i.find("em").text # 电影排行榜
movie["link"] = i.find("div","pic").find("a").get("href") # 电影详情页链接
movie["poster"] = i.find("div","pic").find("a").find('img').get("src") # 电影海报地址
movie["name"] = i.find("span", "title").text # 电影名字
movie["score"] = i.find("span", "rating_num").text # 电影评分
movie["quote"] = i.find("span", "inq").text if(i.find("span", "inq")) else "" # 某些电影没有点评,没有就设为空
lists.append(movie) # 保存到返回数组中
return lists
连接数据库并创建数据表:
# 连接数据库,需指定charset否则可能会报错
db = pymysql.connect(host="localhost",user="root",password="root",db="test",charset="utf8mb4")
cursor = db.cursor() # 创建一个游标对象
cursor.execute("DROP TABLE IF EXISTS movies") # 如果表存在则删除
# 创建表sql语句
createTab = """CREATE TABLE movies(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
rank VARCHAR(4) NOT NULL,
link VARCHAR(50) NOT NULL,
poster VARCHAR(100) NOT NULL,
score VARCHAR(4) NOT NULL,
quote VARCHAR(50)
)"""
cursor.execute(createTab) # 执行创建数据表操作
......
db.close() # 关闭数据库
将提取到的数据存储到数据表中:
# 获取提取到数据
for i in lists:
# 插入数据到数据库sql语句,%s用作字符串占位
sql = "INSERT INTO `movies`(`name`,`rank`,`link`,`poster`,`score`,`quote`) VALUES(%s,%s,%s,%s,%s,%s)"
try:
cursor.execute(sql, (i["name"], i["rank"], i["link"], i["poster"], i["score"], i["quote"]))
db.commit()
print(i[0]+" is success")
except:
db.rollback()

 
完整代码:
import pymysql
import requests
from bs4 import BeautifulSoup
baseUrl = "https://movie.douban.com/top250?start=%d&filter="
def get_movies(start):
url = baseUrl % start
lists = []
html = requests.get(url)
soup = BeautifulSoup(html.content, "html.parser")
items = soup.find("ol", "grid_view").find_all("li")
for i in items:
movie = {}
movie["rank"] = i.find("em").text
movie["link"] = i.find("div","pic").find("a").get("href")
movie["poster"] = i.find("div","pic").find("a").find('img').get("src")
movie["name"] = i.find("span", "title").text
movie["score"] = i.find("span", "rating_num").text
movie["quote"] = i.find("span", "inq").text if(i.find("span", "inq")) else ""
lists.append(movie)
return lists

if __name__ == "__main__":
db = pymysql.connect(host="localhost",user="root",password="root",db="test",charset="utf8mb4")
cursor = db.cursor()
cursor.execute("DROP TABLE IF EXISTS movies")
createTab = """CREATE TABLE movies(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
rank VARCHAR(4) NOT NULL,
link VARCHAR(50) NOT NULL,
poster VARCHAR(100) NOT NULL,
score VARCHAR(4) NOT NULL,
quote VARCHAR(50)
)"""
cursor.execute(createTab)
start = 0
while (start < 250):
lists = get_movies(start)
for i in lists:
sql = "INSERT INTO `movies`(`name`,`rank`,`link`,`poster`,`score`,`quote`) VALUES(%s,%s,%s,%s,%s,%s)"
try:
cursor.execute(sql, (i["name"], i["rank"], i["link"], i["poster"], i["score"], i["quote"]))
db.commit()
print(i["name"]+" is success")
except:
db.rollback()
start += 25
db.close()

楼主低端人口9527

喜欢:(1502)  回复:(5)

0

以下为回复内容


读后有收获可以添加作者微信共同交流
打赏作者

1#楼的低端人口95272017年12月06日 15:42:25回复道:

楼主碉堡了

这我也会!


2#楼的低端人口95272017年12月09日 22:08:33回复道:

低端人口。有感而发!

 

广告呵呵


3#楼的低端人口95272017年12月09日 23:37:57回复道:

终于搞定上传了!


4#楼的爱问知识发布2017年12月11日 14:57:18回复道:

欢迎了解我公司产品!


5#楼的爱问知识发布2017年12月11日 15:05:08回复道:

动态工作原理图




也回复一个  举报