好友
阅读权限30
听众
最后登录1970-1-1
|
本帖最后由 l2430478 于 2021-1-14 15:00 编辑
----------------再次强调,我自学笔记前6个可以直接跳过,学爬虫,直接从笔记七开始就行.
我看豆瓣电影TOP250是爬虫新人必爬对象,我也尝试爬取。
网页地址为:https://movie.douban.com/top250。
在此爬虫中,需要将请求头定制为实际浏览器的请求头。
1、网站分析
打开豆瓣电影TOP250的网站,使用“检查“功能查看该网页的请求头。
把需要的数据复制出来,
User-Agent:
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
Host:
movie.douban.com
然后根据以上信息,做出自己的请求头
[Python] 纯文本查看 复制代码 headers = { 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'Host: movie.douban.com '}
TOP250有个特点,每页只显示25个电影,如果要获取所有的250页电影,就需要获取总共10页的内容。
通过单击第二页可以发现网页地址变成了:https://movie.douban.com/top250?start=25第三页的地址为:https://movie.douban.com/top250?start=50。规律是每多一页,就给网页地址的start参数加上25。
通过以上分析发现,可以使用requests获取电影网页的代码,并利用for循环翻页。
仔细扣,又发现https://movie.douban.com/top250?start=0&filter= 也能看到排行。
尝试想用上几个帖子写的代码进行headers进行请求,结果返回的不是200,说明该网也进行了反爬。
询问朋友,他让我加一个timeout参数
html = requests.get(url, headers=headers,timeout=30)
请求成功返回状态码200
print(html.status_code)
我们这次在网页上点击查看源代码,发现每个 <li> </li>之间为每个电影的所有信息。而 </li>结束之后,即为下一个电影<li>的开始。也就是说,每个 <li> </li>是独立的,我们只需要把这250个 <li> </li>的信息提取出来即可。
继续深入分析可知,我们需要的信息都被<div class="info">所包含
那我们分成一小块一小块来解决问题,先用xpath解析出class属性为info的div块
root.xpath('//div[@class="info"]')
继续深入分析,每段代码的含义如下:
[Python] 纯文本查看 复制代码 # 影片名称
title = InformationBlock.xpath('div[@class="hd"]/a/span[@class="title"]/text()')[0]
# print(title)
info = InformationBlock.xpath('div[@class="bd"]/p[1]/text()')
# print(type(info))
directorAndStarring = str(info[0]).split(" ")
# 导演
director = directorAndStarring[0].replace(" ", "").replace("\n", "").replace("导演:", "")
# 主演
try:
Starring = directorAndStarring[1].replace(" ", "").replace("\n", "").replace("主演:", "")
except :
Starring = "NULL"
# 上映日期
date = info[1].replace(" ", "").replace("\n", "").split("/")[0]
# 制片国家
country = info[1].replace(" ", "").replace("\n", "").split("/")[1]
# 影片类型
geners = info[1].replace(" ", "").replace("\n", "").split("/")[2]
# 评分
rate = InformationBlock.xpath('div[@class="bd"]/div/span[2]/text()')[0]
# 评论人数
comCount = InformationBlock.xpath('div[@class="bd"]/div/span[4]/text()')[0].replace("人评价", "")
这样,我们就找到需要的信息了,现在就可以获取信息保存在本地,代码如下:
[Python] 纯文本查看 复制代码 datas = (("{},{},{},{},{},{},{},{},{}").format(Top, title, director, Starring, rate, date, country, geners, comCount))
with open("doubanMovie.csv", "a", newline="", encoding="utf_8_sig") as f:
f.write(datas+"\n")
Top为设定的全局变量
此文件使用追加模式,即此处的open()函数第二个参数为"a"
encoding编码格式,此处有坑,之前笔者用"utf-8"格式向csv文件写入数据,csv文件打开后中文乱码,查找了不少资料,最后发现使用"utf_8_sig"格式有效解决问题
以上三步可以完成单页的爬取,但是Top250被分成了10页,让我们看看它剩下几页url的规律
[Python] 纯文本查看 复制代码 第一页
[url=https://movie.douban.com/top250?start=0&filter=]https://movie.douban.com/top250?start=0&filter=[/url]
第二页
[url=https://movie.douban.com/top250?start=25&filter=]https://movie.douban.com/top250?start=25&filter=[/url]
第三页
[url=https://movie.douban.com/top250?start=50&filter=]https://movie.douban.com/top250?start=50&filter=[/url]
...
最后一页
[url=https://movie.douban.com/top250?start=225&filter=]https://movie.douban.com/top250?start=225&filter=[/url]
每一页url的start= 后跟的参数从0开始,每页增加25,最大为225,OK分析完成
[Python] 纯文本查看 复制代码 # 翻页
def nextPage():
for i in range(0, 250, 25):
url = 'https://movie.douban.com/top250?start={}&filter='.format(i)
getInfo(url)
其代码如下:
[Python] 纯文本查看 复制代码 """
电影Top250主页 (需翻页;翻页url:("https://movie.douban.com/top250?start={}&filter=").format(i),i = i + 25)
获取信息存储于csv文件中
"""
from lxml import etree
import requests
headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
Top = 1
# 获取信息
def getInfo(url):
html = requests.get(url, headers=headers, timeout=30)
# print(html.status_code)
root = etree.HTML(html.content)
# 我们所需要的所有的信息都在<div class="info">块中
for InformationBlock in root.xpath('//div[@class="info"]'):
# 影片名称
title = InformationBlock.xpath('div[@class="hd"]/a/span[@class="title"]/text()')[0]
# print(title)
# <div class="bd">块,导演、演员、上映时间、制片国家、影片类型在一个<p>里
info = InformationBlock.xpath('div[@class="bd"]/p[1]/text()')
# print(type(info))
'''
导演主演 info[0]
'''
directorAndStarring = str(info[0]).split(" ")
# 导演
director = directorAndStarring[0].replace(" ", "").replace("\n", "").replace("导演:", "")
# 主演
try:
Starring = directorAndStarring[1].replace(" ", "").replace("\n", "").replace("主演:", "")
except :
Starring = "NULL"
'''
上映日期、制片国家、影片类型 info[1]
'''
# 上映日期
date = info[1].replace(" ", "").replace("\n", "").split("/")[0]
# 制片国家
country = info[1].replace(" ", "").replace("\n", "").split("/")[1]
# 影片类型
geners = info[1].replace(" ", "").replace("\n", "").split("/")[2]
# 评分
rate = InformationBlock.xpath('div[@class="bd"]/div/span[2]/text()')[0]
# 评论人数
comCount = InformationBlock.xpath('div[@class="bd"]/div/span[4]/text()')[0].replace("人评价", "")
global Top
# 打印结果看看
print(Top, title, director, Starring, rate, date, country, geners, comCount)
print("---------------------------------------------------------")
datas = (("{},{},{},{},{},{},{},{},{}").format(Top, title, director, Starring, rate, date, country, geners, comCount))
with open("doubanMovie.csv", "a", newline="", encoding="utf_8_sig") as f:
f.write(datas+"\n")
Top += 1
# 翻页
def nextPage():
for i in range(0, 250, 25):
url = 'https://movie.douban.com/top250?start={}&filter='.format(i)
getInfo(url)
if __name__ == '__main__':
# 给文件加头部标题
with open("doubanMovie.csv", "w", newline="", encoding="utf_8_sig") as f:
f.write("Top,title,director,Starring,rate,date,country,geners,comCount"+"\n")
nextPage()
------------------------几个小白常识
|||from lxml import etree #表示是 从 lxml 这个库中导入 etree (需要安装 lxml包)
|||import requests #表示是调用requests包
|||headers = 一串字符 就是模拟用户访问 防网址反爬 你就调取不了数据
|||如果你把Top = 1 去了 爬取的将是继续爬,举例你第一次爬取的是1-250,那么删除Top = 1后,第二次将从251开始继续存档,但数据还是这相同的250个。
|||def getInfo(url): 代表定义一个函数,我们可以定义一个由自己想要功能的函数,以下是简单的规则:1.函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。2.任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
3.函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。4.函数内容以冒号起始,并且缩进。5.return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
|
免费评分
-
查看全部评分
|