首先,写爬虫的时候大致有以下四个内容需要考虑:
1、url地址的获取:
①要是知道url地址的规律和总体页码数情况,我们可以较容易的构造处url地址的列表;
②当我们不知道url地址的一些规律时,就需要先构造一个start_url来获取初始地址,然后再请求,再生成。
2、发送请求,获取响应(利用requests库)
3、提取数据:
①返回的是json字符串(json.loads()转化为python对象)
②返回的是html字符串(lxml模块配合xpath提取数据)
4、保存数据
搞清楚爬虫的大致步骤后,便可以按照这个思路一步步进行了
观察豆瓣电影top250的网页地址规律,可以很容易发现每页url地址中的start={}都会比前一页增加25,一共有十页。
故我们自然可以想到利用一个循环来完成对url列表的构造
temp_url = "https://movie.douban.com/top250?start={}&filter="
i = 0
while i <= 225:
# 构造每页url
url = self.temp_url.format(i)
print(url)
构造结果如下图,和我们实际翻页看到了url地址一样。
然后,我们需要对每个url地址发送请求,获取响应。
response = requests.get(url, headers=self.headers)
html_str = response.content.decode("utf-8")
此时获得的html_str便是从豆瓣电影某一页爬下来的html字符串,我们还需要将它转换成xpath能处理的对象,以便后续的数据整理。
html = etree.HTML(html_str)
获取到了我们想要的数据,接下来我们就要从这一堆数据中提取出电影,电影导演、主演,评分,评论人数等一系列具体数据。
对于这一系列的数据可以利用xpath语法来定位各个数据的标签:
datas = html.xpath("//ol[@class='grid_view']/li")
for data in datas:
item = {}
item["title"] = data.xpath('div/div[2]/div[@class="hd"]/a/span[1]/text()')
item["info"] = data.xpath('div/div[2]/div[@class="bd"]/p[1]/text()')
item["score"] = data.xpath('div/div[2]/div[@class="bd"]/div/span[@class="rating_num"]/text()')
item["num"] = data.xpath('div/div[2]/div[@class="bd"]/div/span[4]/text()')
最后,保存到txt文件中。
with open('douban250.txt', 'a', encoding='utf-8')as f:
f.write(str(self.num) + '.' + str(item["title"][0]) + '\n')
f.write((item["info"][0]).strip() + '\n')
f.write(str(item["info"][1]).strip() + '\n')
f.write("评分:" + str(item["score"][0]) + '\n')
f.write(str(item["num"][0]) + '\n')
f.write('\n' * 3)
运行结果:
源代码:
from lxml import etree
import requests
class DoubanSpider:
def __init__(self):
self.temp_url = "https://movie.douban.com/top250?start={}&filter="
self.headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3722.400 QQBrowser/10.5.3751.400"}
self.num = 1 #排名
def content_list(self,html):
datas = html.xpath("//ol[@class='grid_view']/li")
for data in datas:
item = {}
item["title"] = data.xpath('div/div[2]/div[@class="hd"]/a/span[1]/text()')
item["info"] = data.xpath('div/div[2]/div[@class="bd"]/p[1]/text()')
item["score"] = data.xpath('div/div[2]/div[@class="bd"]/div/span[@class="rating_num"]/text()')
item["num"] = data.xpath('div/div[2]/div[@class="bd"]/div/span[4]/text()')
with open('douban250.txt', 'a', encoding='utf-8')as f:
f.write(str(self.num) + '.' + str(item["title"][0]) + '\n')
f.write((item["info"][0]).strip() + '\n')
f.write(str(item["info"][1]).strip() + '\n')
f.write("评分:" + str(item["score"][0]) + '\n')
f.write(str(item["num"][0]) + '\n')
f.write('\n' * 3)
self.num += 1
def run(self): # 实现主要逻辑
i = 0
while i <= 225:
# 构造每页url
url = self.temp_url.format(i)
#print(url)
# 发送请求,获得返回的html代码并保存在变量html_str中
response = requests.get(url, headers=self.headers)
html_str = response.content.decode("utf-8")
#print(html_str)
# 使用etree处理数据, 将返回的字符串格式的html代码转换成xpath能处理的对象
html = etree.HTML(html_str)
#print(html)
# 定位标签,保存数据
self.content_list(html)
i+=25
if __name__ == '__main__':
douban = DoubanSpider()
douban.run()