一、页面分析
1.1 单页分析
目标url:https://movie.douban.com/top250?start=0&filter=
本次的爬取目标主要是:标题、评分、评价人数、引言、电影链接
由于该网页为静态网页,所以上手的难度也大大减少。
进入开发者工具 寻找我们要爬取的数据所在位置(由于是静态的网页所以直接f12在Elements找)
1、电影名称(标题)
2、评分
3、评价人数
4、引言
5、电影链接
找到了对应的数据所在位置后就可以用xpath工具来确定一下他们的起始位置
通过工具可以发现一共有25个搜索结果,对应的也就是一个页面的25部电影的信息。所以我们在写代码的时候就可以以这个路径为基础路径从而进一步的查找我们要找到的信息
1、电影名称解析
//div[@class="info"]/div[@class="hd"]/a/span/text()
2、评分解析
//div[@class="info"]/div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()
3、评价人数解析
//div[@class="info"]/div[@class="bd"]/div[@class="star"]/span[last()]/text()
注:评价人数由于没有class属性定位不到这条数据,所以就用了last()就可以直接定位到span里的最后一条数据。
4、引言解析
//div[@class="info"]/div[@class="bd"]/p[@class="quote"]/span/text()
引言这块有个小坑,就是有些电影会没有引言,如果所有的引言都按照这个格式写就会出现报错,所以我们需要添加一个判断来跳过这个坑
# 如果有引言就写引言,没有就不写
if quote:
quote = quote[0]
else:
quote = ''
5、电影链接解析
//div[@class="info"]/div[@class="hd"]/a/@href/text()
1.2 翻页分析
翻页是为了让我们除了能爬第一页之外,还可以把我们想爬的页数都爬出来。我们首先先来分析一下url的差别
# 第一页
https://movie.douban.com/top250?start=0&filter=
# 第二页
https://movie.douban.com/top250?start=25&filter=
# 第三页
https://movie.douban.com/top250?start=50&filter=
通过观察不难发现三个网址不同的地方在start值,并且分别是以25 25 25逐次递加的,进行一下测试,把start值改成75看一下会不会跳转去第4页
可以看到,改变了值了以后确实成功的跳转页面了,也就证明我们的猜想是正确的,接下来就可以通过一个循环来实现这个功能了
start = int(input('输入要爬取的起始页:'))
end = int(input('输入要爬取的末尾页:'))
for i in range(start, end+1):
time.sleep(2)
page = (i-1) * 25
得到了这个start的值后我们就需要进行拼接url的功能实现
com_url = 'https://movie.douban.com/top250?start=' + str(page)
至此,分析也就算结束了。
二、完整代码
import requests
from lxml import etree
import csv
import time
class DoubanSpider(object):
def __init__(self):
self.header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36'
}
# 发请求 获响应
def get_source(self, com_url):
res = requests.get(com_url, headers=self.header)
html = res.content.decode('utf-8')
return html
# 解析数据
def parsed_source(self, html):
tree = etree.HTML(html)
divs = tree.xpath('//div[@class="info"]')
# print(divs)
lis_data = []
for div in divs:
d = {}
# 标题
title = div.xpath('./div[@class="hd"]/a/span/text()')[0].strip()
# print(title)
# 评分
score = div.xpath('./div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')[0].strip()
# print(score)
# 评价人数
evaluate = div.xpath('./div[@class="bd"]/div[@class="star"]/span[last()]/text()')[0].strip()
# print(evaluate)
# 引用
quote = div.xpath('./div[@class="bd"]/p[@class="quote"]/span/text()')
if quote:
quote = quote[0]
else:
quote = ''
# 电影链接url
link_url = div.xpath('./div[@class="hd"]/a/@href')[0].strip()
# print(link_url)
# 根据key值提取数据
d['title'] = title
d['score'] = score
d['evaluate'] = evaluate
d['quote'] = quote
d['link_url'] = link_url
lis_data.append(d)
# print(lis_data)
return lis_data
# 保存数据
def save_source(self, move_data, header):
with open('movie_data.csv', 'a', encoding='utf-8-sig', newline='') as f:
w = csv.DictWriter(f, header)
# 写入表头
w.writeheader()
# writerows 一次性写入多行数据
w.writerows(move_data)
# 主函数
def main(self):
start = int(input('输入要爬取的起始页:'))
end = int(input('输入要爬取的末尾页:'))
for i in range(start, end+1):
time.sleep(2)
page = (i-1) * 25
com_url = 'https://movie.douban.com/top250?start=' + str(page)
h = self.get_source(com_url)
# print(h)
print('爬虫机器人正在爬取第%d页' % i)
move_data = self.parsed_source(h)
# 设置表头
header = ['title', 'score', 'evaluate', 'quote', 'link_url']
# print(move_data)
self.save_source(move_data, header)
if __name__ == '__main__':
# 实例化对象
Spider = DoubanSpider()
# 主函数调用
Spider.main()
三、运行结果