爬取网址:https://movie.douban.com/top250
爬取信息:电影名称,导演,主演,类型,制片国家,上映时间,片长,评分
爬取方式:进入详细页面爬取,lxml,re解析。
存储方式:MySQL存储
使用MySQL存储,首先需要在SQLyog中建立数据表:
CREATE TABLE topmovies (
电影名称 TEXT,
导演 TEXT,
主演 TEXT,
类型 TEXT,
制片地 TEXT,
上映时间 TEXT,
片长 TEXT,
评分 TEXT
)ENGINE INNODB DEFAULT CHARSET=utf8;
注意:中文字段无需用""括起来,不能写成:"电影名称" TEXT。
然后在快捷菜单中选择“执行查询”或使用F9键执行代码,即可完成数据表的创建。
代码如下:
import requests
from lxml import etree
import re
import pymysql
import time
def get_details_url(url):
r = requests.get(url,headers = headers)
html = etree.HTML(r.text)
movie_urls = html.xpath('//div[@class="pic"]/a/@href')
return movie_urls
def get_info(url):
r = requests.get(url,headers=headers)
html = etree.HTML(r.text)
try:
name = html.xpath('//div[@id="content"]/h1/span[1]/text()')[0]
director = html.xpath('//div[@id="info"]/span[1]/span[2]/a/text()')[0]
actor1 = html.xpath('//div[@id="info"]/span[3]/span[2]')[0]
actor = actor1.xpath('string(.)')
style1 = re.findall('<span property="v:genre">(.*?)</span>',r.text,re.S) ##若采用xpath的标签定位,有可能发生爬取数据错位。
style = '/'.join(style1)
country = re.findall('制片国家/地区:</span>(.*?)<br/>',r.text,re.S)[0].strip()
release_time1 = re.findall('<span property="v:initialReleaseDate" content="(.*?)">',r.text,re.S)
release_time = '/'.join(release_time1)
run_time = re.findall('片长:</span> <span.*?>(.*?)</span>',r.text,re.S)[0]
score = re.findall('property="v:average">(.*?)</strong>',r.text,re.S)[0]
#print(name,director,actor,style,country,release_time,run_time,score)
cursor.execute('INSERT INTO topmovies(电影名称,导演,主演,类型,制片地,上映时间,片长,评分) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)',
(name,director,actor,style,country,release_time,run_time,score))
except IndexError:
pass ##忽略IndexError,因为有些影片的详细页面没内容。
if __name__ == "__main__":
conn = pymysql.connect(host='localhost',user='root',db='mydb',port=3306,charset="utf8") #连接数据库
cursor = conn.cursor() #光标对象
headers = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3294.6 Safari/537.36'}
url_list = ['https://movie.douban.com/top250?start={}&filter='.format(i*25) for i in range(0,10)] #共10页
for url in url_list:
movie_urls = get_details_url(url)
for movie_url in movie_urls:
get_info(movie_url)
time.sleep(2)
conn.commit() #提交事务
结果为:
可以看到,总共获取了245个数据。如果要获得完整数据,也可以考虑把概述页的内容提取出来,即遇到Indexerror后提取电影的概述数据。
数据库中的信息样式为: