1.对豆瓣网页进行分析
使用谷歌浏览器,找到网页代码,查看请求头的信息
需要注意的是,我们要爬取的页面数据文件是top250这个文件,判断需要从哪个包中提取数据可以在响应里看到:
我们可以试着向豆瓣发送请求:
import requests
# 发请求测试
response = requests.get('https://movie.douban.com/top250')
print(response)
响应结果如下:
状态码是418,意思是服务器拒绝了我们的请求。这是因为服务器没有识别到我们是用户端,所以为了保证网站数据的安全,将我们拒之门外。那么我们就需要对自己进行一些简单的伪装。
UA(user-agent)伪装,是我本次采用的伪装策略,也是最简单的伪装策略,有些网站的反爬机制比较复杂,则需要采用更加复杂的反反爬机制来进行伪装,不过,对于豆瓣来说,UA伪装就够用了。
那么我们现在给我们的请求带一个请求头,并且请求头中带一个User-agent信息,这个信息可以在检查页面的请求头信息(Headers)里找到,如下所示:
现在我们将它加入到我们的代码中:
import requests
# 发请求测试网站反爬机制
headers = {
'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1'
}
response = requests.get('https://movie.douban.com/top250',headers=headers)
print(response)
响应结果如下:
状态码200 ,表示响应成功,此时可以打印一下请求成功的数据:
print(response.text)
可以看到,我们已经得到了整个页面的html代码,那么下一步我们就需要从中提取我们需要的信息。
我这里提取的信息是电影名,星级评价,用户评分,评价人数
采用的python库是bs4,检查网页代码之后发现需要的数据储存的位置:
可以看到电影的信息都在<li>.....<li>中的,我们拿到本页面的html代码之后开始解析数据。
拿到我们需要的数据块:
soup = BeautifulSoup(response.text, "html.parser")
article_items = (soup.find("div", class_="article")
.find("ol", class_="grid_view")
.find_all("div", class_="item")
)
运行结果:
此时返回的结果是一个列表。接下来就获取我们想要的5个值:
for article_item in article_items:
rank = article_item.find("div", class_="pic").find("em").get_text() # 排名
title = article_item.find("div", class_="info") \
.find("div", class_="hd") \
.find("span", class_="title").get_text() # 电影名称
stars = (
article_item.find("div", class_="info")
.find("div", class_="bd")
.find("div", class_="star")
.find_all("span")
)
rating_star = stars[0]["class"][0] # 星级评价
rating_num = stars[1].get_text() # 用户总体评分
comments = stars[3].get_text() # 评价人数
得到的结果:
输入excle表格就行。
完整代码:
import requests
from bs4 import BeautifulSoup
import pandas as pd
def parse_single_html(html):
"""
负责解析html页面,获取目标数据
:param html:
:return:[rank,title,"星级排名","用户总体评分","评价人数"]
"""
soup = BeautifulSoup(html, "html.parser")
article_items = (soup.find("div",class_="article")
.find("ol",class_="grid_view")
.find_all("div",class_="item")
)
datas = []
for article_item in article_items:
rank = article_item.find("div", class_="pic").find("em").get_text() # 排名
title = article_item.find("div", class_="info") \
.find("div", class_="hd") \
.find("span", class_="title").get_text() # 电影名称
stars = (
article_item.find("div", class_="info")
.find("div", class_="bd")
.find("div", class_="star")
.find_all("span")
)
rating_star = stars[0]["class"][0] # 星级评价
rating_num = stars[1].get_text() # 用户总体评分
comments = stars[3].get_text() # 评价人数
datas.append({
"rank": rank,
"title": title,
"rating_star": rating_star.replace("rating", "").replace("-t", ""),
"rating_num": rating_num,
"comments": comments.replace("人评价", "")
})
return datas
root_url = "https://movie.douban.com/top250"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
}
# 制作10个网页的url
sum = 0
htmls = []
for i in range(0, 10):
page = '?start=' + str(sum) + '&filter='
url = root_url + page
response = requests.get(url, headers=headers)
if response.status_code != 200:
raise Exception("error")
htmls.append(response.text)
sum += 25
all_datas = []
for html in htmls:
all_datas.extend(parse_single_html(html))
df = pd.DataFrame(all_datas)
df.to_excel("豆瓣电影TOP250.xlsx")