爬虫入门示例–百度首页(Get请求)
一、前文
在前置知识阶段,我们提到了爬虫的业务流程,后续也将按照流程顺序进行学习。
1.确定数据所在的地点,数据往往存在于页面源代码或者api接口(数据包)中。其中静态资源大概率会存在于页面源代码中,动态资源用api接口实时请求。这个你可以想象为
2.对数据对应的url发送请求拿取数据(在这一步往往会有反爬技术,后续会讲解)
3.对数据进行处理,展示(关于数据提取,后文会讲解,本文不介绍)
python使用requests模块发送进行请求
下面我们就从百度的首页进行讲解。
二、具体操作
①.我们去找到百度的logo和百度热搜的数据位置
i.百度logo
前文说到,这种不会发生改变的资源,一般会会在页面源代码中,F12打开开发者工具,检查元素,将鼠标拖动到logo处点击。
可以发现这个logo是一个img标签,里面有
src="//www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"
这个就是我们需要的
ii.百度热搜
一样的检查元素,移动到热搜上的任意一条,只要找到大致范围即可
可以发现,热搜的内容是一个ul列表,li标签下的a标签里面的
href="https://www.baidu.com/s?wd=%E4%B9%A0%E8%BF%91%E5%B9%B3%E5%A4%8D%E4%BF%A1%E9%98%BF%E8%81%94%E9%85%8B%E5%AD%A6%E7%94%9F%E4%BB%A3%E8%A1%A8&sa=fyb_n_homepage&rsv_dl=fyb_n_homepage&from=super&cl=3&tn=baidutop10&fr=top1000&rsv_idx=2&hisfilter=1"
就是我们热搜内容的具体搜索地址
②发送数据拿到内容
下面我们就正式开始用代码去抓取我们需要的数据
i.logo的获取
在F12中我们可以查看页面源代码是用Get直接发送的(大部分不需要提交表单的请求都是Get请求,有表单的,比如说登录的时候要提交信息,发布文章的时候要提交信息,这种一般是Post请求。)
1.我们先做最简单的,直接用requests发送请求
import requests
url = "https://www.baidu.com/" #目标url
resp = requests.get(url) #利用requests发送Get resp为response的缩写
content = resp.content #resp.content表示resp的响应内容
print(content)
2.可以发现,上面是一些看不懂的编码,这些编码其实是16进制,一半请求没有正常响应就考虑是否存在反爬。常见反爬手段可参考:9种常见的反爬虫策略思路 - 知乎https://zhuanlan.zhihu.com/p/345343134
下面我们先加入一个header请求头,其中包括User-Agent
User-Agent的查找,在F12中随便找到一个资源,然后点击,打开标头,拉到最下面,就会又UA了
新的代码:
import requests
url = "https://www.baidu.com/"
_headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0'
}
resp = requests.get(url,headers=_headers)
content = resp.content
print(content)
新的输出:
此时我们可以发现,多出了很多东西,证明我们应该是正常请求了,此时使用ctrl
+F
进行搜索,搜索logo所在的img标签,此处我使用的标签的id号,因为一个页面,标签的id号一般是唯一的。
根据上图,可以发现我们正确的找到了logo图片的url的位置。
ii.热搜列表的获取
通过a标签的id定位,我们可以发现热搜榜单上面的内容的url
在这点请注意下面这个问题,返回的响应内容的ul标签以及下面的li标签的class属性与F12看到的不同
这个时候请以响应内容为主,同时当你数据处理的时候,发现代码没问题,但就是拿不到数据的时候,也请查看响应内容,做出适当的调整。
三、数据处理
本次文章只展示代码,不做讲解,后续文章会对时间处理的方式进行讲解。
i.公用部分代码:
import requests
from lxml import etree
import pandas as pd
url = "https://www.baidu.com/"
_headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0'
}
resp = requests.get(url,headers=_headers)
resp.encoding = 'utf-8'
content = resp.content
# print(content)
html = etree.HTML(content)
ii.百度logo
logo_url ='https:'+ html.xpath('//img[@id="s_lg_img"]/@src')[0]
print(logo_url)
with open("./logo.img",mode='wb')as f:
img_content = requests.get(logo_url).content
f.write(img_content)
iii.百度热搜榜单
data = []
data_list = html.xpath('//ul[@id="hotsearch-content-wrapper"]//li')
for data_e in data_list:
title = data_e.xpath('.//text()')[2]
url = data_e.xpath('.//a/@href')[0]
print(f"title: {title}\nurl: {url}")
data.append({"title":title,"url":url})
df = pd.DataFrame(data)
# 检查是否存在 Excel 文件,如果不存在则创建一个新的
try:
existing_df = pd.read_excel('data.xlsx')
# 将新数据追加到现有 Excel 文件中
df = pd.concat([existing_df, df], ignore_index=True)
except FileNotFoundError:
# 创建一个新的 Excel 文件
pass
# 将 DataFrame 写入 Excel 文件
df.to_excel('data.xlsx', index=False)
结果展示
四、结语
PS:有时候页面源代码,F12的检查元素以及返回的响应内容三者得到的结果都会略有不同,这个时候我们可以发送多次请求,查看是因为网络波动导致数据异常,还是本身请求的有问题导致响应内容和页面源代码以及F12得到的结果不同。如果发现是响应内容就是不对的,这个时候我们要以相应内容为主,去分析响应内容,不要纠结为什么不同或者没有发现有不同的地方,从而导致开发效率降低。
有任何问题欢迎大家的评论和指正。再次声明,本专栏只做技术探讨,严谨商用,恶意攻击等。
这是我的 GitHub 主页:Rosyrain (github.com) https://github.com/rosyrain
,里面有一些我学习时候的笔记或者代码。本专栏的文档和源码存到spider-course的仓库下。
欢迎大家Follow/Star/Fork三连。