前言:为了符合我这个强迫症患者,有了问答界面,没有数据怎么办捏,所已,又写了一个爬虫,爬取百度百科页面
注意:没什么注意的只是百度百科用了异步加载,比较麻烦
异步加载是什么捏,emmmmmmmmmmm就是在我们普通的页面中是可以再源代码中找到网页上显示的超链接,异步加载只不过是没有吧链接放到源代码中,所以普通的方法肯定就不行了,那麽他的链接到底在哪儿捏?????
可以看到源代码里是没有任何与页面相关的url,
而所有的url和词条信息在另一个网址中
打开检查,进入网络中可以看到有很多请求
异步加载的网址在xhr的getlemmas中,异步请求的网址:
点击网址查看内容,一看实锤
找到异步数据的url后,就可以发送请求了
但是也不能用普通的get方法注意看,他的请求方式为POST这就需要提交表单,表单的内容在哪儿捏?
下拉可以看到表单数据
这里解释一下表单中的limit是每一页有多少个词条(一页是24个)tagID是分类如科学百科健康医疗分类的tagId=76625而科学百科航空航天分类的tagId=76572,那page自然就是页数咯
做到了这些还不够,返回的数据是json类型的
知道了这些就可以构造词条的URL了
分析一下词条的URL由词条名称和ID组成,获取词条名称和ID就可以构造一个完整的URL了
说了这么多,上代码
# -*- coding: UTF-8 -*-
import requests
from lxml import etree
import json
import sys
import time
class Spider:
def __init__(self):
# 定义请求头
self.UserAgent = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"}
def main(self):
index_url = "https://baike.baidu.com/wikitag/taglist?tagId=76613" #从这里开始
post_url = "https://baike.baidu.com/wikitag/api/getlemmas" #异步数据加载的URL
params = {
"limit": 24,
"timeout": 3000,
"tagId": 76613,
"fromLemma": False,
"contentLength": 40,
"page": 0
} #异步时需要的请求对象
res = requests.post(post_url, params, headers=self.UserAgent) #POST异步请求数据
jsonObj = res.json() #解析成字典类型
totalpage = jsonObj['totalPage'] #读出来你所有页数
print("=======================\n总页面有"+str(totalpage)+"\n=======================\n")
hope=int(input('请输入要下载多少页:'))#希望下载多少页
page = 0#更改起始页面hope+1
while page <= hope: #变量页数采集所有页码的文件
self.list_url(page) #进行第一步采集POST异步数据采集
print('当前页面:'+str(page)+'已下载完毕')
page = page + 1
print('正在下载'+str(page))
def list_url(self,page):
post_url = "https://baike.baidu.com/wikitag/api/getlemmas"
params = {
"limit":24,
"timeout":3000,
"tagId":76625,
"fromLemma":False,
"contentLength":40,
"page":page
}#tagID更改分类limit指每一页下载多少个,一页24个
res = requests.post(post_url,params,headers=self.UserAgent)
jsonObj = res.json()
lemmaList = jsonObj['lemmaList'] #取出数据区域
for key in lemmaList: #遍历数据区域提取可用字段
self.baike(key['lemmaUrl'],key['lemmaTitle']) #进行第二步元素采集
def baike(self,url,key):
res = requests.get(url,headers=self.UserAgent)
res.encoding="UTF-8"
select = etree.HTML(res.text) #使用通俗易懂的Xpath解析HTML
text = select.xpath("string(//div[@class='lemma-summary'])") #选择HTML节点
killbr = text.replace("\n","") #把换行去掉
f = open(sys.path[0] + "\data.txt",'a',encoding="utf-8") #在运行目录创建一个TXT文本存储结果并追加模式打开
f.write(key+"@"+killbr+"\n") #保存结果
f.close() #关闭句柄
print("=======================\n"+key+"++采集并输出完毕"+"\n=======================\n") #把采集的进度显示
if __name__ == '__main__':
spider = Spider() #实例化
spider.main() #执行main入口方法
还是老样子,附上效果图,亲测可用人头担保
至此结束~~===================================~~