爬取豆瓣电影电影top250这种操作已经满足不了我们的需求,这种低端操作所需要的信息都存在于网页的源代码中,只需要使用xpath提取html信息就能完成操作。
需要注意的有三点:1.xpath工具的使用;2.使用text()提取html标签文本内容;3.异常的处理。
# created on July 24 2018
# author:Achilles
#爬取豆瓣top250电影
import requests
from lxml import etree
with open("D:\豆瓣电影top250.txt","w",encoding="utf-8") as f:
count = 0
for i in range(10):
url = "https://movie.douban.com/top250?start={}".format(i * 25)
headers = {"User_Agent":"Mozilla/5.0(compatible; NSIE 5.5; Windows10)"}#防止服务器拒绝访问
data = requests.get(url,headers=headers).text
s = etree.HTML(data)
movies = s.xpath('//*[@id="content"]/div/div[1]/ol/li')
for movie in movies:
count += 1
movie_name_chines = movie.xpath("./div/div[2]/div[1]/a/span[1]/text()")[0].strip()
movie_name_normal = movie.xpath("./div/div[2]/div[1]/a/span[2]/text()")[0].strip()
movie_staff = movie.xpath("./div/div[2]/div[2]/p[1]/text()")[0].strip()
movie_year = movie.xpath("./div/div[2]/div[2]/p[1]/text()")[1].strip()
movie_mark = movie.xpath("./div/div[2]/div[2]/div/span[2]/text()")[0].strip()
movie_mark_people = movie.xpath("./div/div[2]/div[2]/div/span[4]/text()")[0].strip()
try:#防止有的电影没有描述,抛出异常
movie_desc = movie.xpath("./div/div[2]/div[2]/p[2]/span/text()")[0].strip()
except IndexError:
movie_desc = "暂无描述"
f.write("电影排名: {}\n".format(count))
f.write("电影名字: {}(译名)\t{}(原名)\n".format(movie_name_chines,movie_name_normal))
f.write("电影职员: {}\n".format(movie_staff))
f.write("电影年份: {}\n".format(movie_year))
f.write("电影评分: {}({})\n".format(movie_mark,movie_mark_people))
f.write("电影描述: {}\n".format(movie_desc))
f.write("\n")
由于笔者最近沉迷权力的游戏和行死走肉等美剧,爬取完豆瓣电影top250后就想着爬取豆瓣上所有的美剧,很自然地使用了以下方法来爬取:
1.进入豆瓣首页找到美剧的url:
https://movie.douban.com/tv/#!type=tv&tag=%E7%BE%8E%E5%89%A7&sort=rank&page_limit=20&page_start=0
2.刚开始只爬取20个作为示范,网页url的意思很明确,每页20个,从0开始
3.找到相关信息的xpath
4.编写代码
# created on July 25 2018
# author:Achilles
#爬取豆瓣美剧
import requests
from lxml import etree
with open("D:\AmericanSeries.txt", "w", encoding="utf-8") as f:
url = "https://movie.douban.com/tv/#!type=tv&tag=%E7%BE%8E%E5%89%A7&sort=rank&page_limit=20&page_start=0"
headers = {"User_Agent": "Mozilla/5.0(compatible; NSIE 5.5; Windows10)"} # 防止服务器拒绝访问
data = requests.get(url, headers=headers).text
# data = urllib.request.urlopen(url).read()
s = etree.HTML(data)
movies = s.xpath('//*[@id ="content"]/div/div[1]/div/div[4]/div/a')
for movie in movies:
movie_name = movie.xpath("./p/text()")
movie_mark = movie.xpath("./p/strong/text()")
f.write("美剧名字:\t{}".format(movie_name))
f.write("美剧评分:\t{}".format(movie_mark))
f.write("\n")
代码很简单,然而运行后并不能得到结果,调试发现movies是个空列表,确认xpath路径无误,于是查看网页源代码,发现网页源代码中没有我们需要的美剧信息。百度后发现这种情况通常是因为网站使用了动态生成技术来保护网站的信息。
于是参考这篇文章:https://blog.csdn.net/qq523176585/article/details/78693900的方法二,仔细检查网站的相关请求
发现这正是我们想要的美剧信息,右键,open in new tab ,发现这是一个json列表。
到这一步后,爬取美剧的难点已经得到解决,接下来的操作主要是针对这个列表展开。
#created on July 29 2018
#autor:Achilles
import requests
with open("D:\AmericanSeriseInDouban.txt","w",encoding="utf-8") as f:
url = \
"https://movie.douban.com/j/search_subjects?type=tv&tag=%E7%BE%8E%E5%89%A7&sort=rank&page_limit=99999&page_start=0"
dict = requests.get(url).json()
lists = dict['subjects']
count = 1
for list in lists:
movie_name = list["title"]
movie_mark = list["rate"]
movie_http = list["url"]
f.write("美剧排名: \t{}\n".format(count))
f.write("美剧名字: \t{}\n".format(movie_name))
f.write("美剧评分: \t{}\n".format(movie_mark))
f.write("美剧地址: \t{}\n".format(movie_http))
f.write("\n")
count += 1
爬取成功:
可惜此网站接口仅存储了500个美剧信息,无法访问更多。
爬取豆瓣所有美剧的爬虫在业余时间会陆续更新。