目录
从输出的文本内容显示body标签段能获取到我们需要的数据内容:
1.从body标签段再具体缩小到div标签段,爬取此标签的数据内容,为分类出所需信息做准备:
重新在页面的Response里格式化一下代码,观察页面的代码格式,最后通过所需字段标签的属性内容来定位,逐个爬取相应字段:
后续思考认为不必在爬取时连续用两个find,只需在整体的属性内容下定位到字段直接对应的属性内容
仅为学习流程的记录,不是完整的项目记录,不具有充分的逻辑性
来到bd热搜小说榜的界面:
初步决定爬取以下的几个要素:热度、书名、作者、类型、说明
获取wb
# 先导入包
import requests
# 添加header请求头,防止被拦截
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'}
# 获取百度热搜小说榜的地址,以resp对象存储
resp=requests.get("https://top.baidu.com/board?tab=novel",headers=headers)
# 输出一下获取的网站,resp.text是返回headers中的编码解析的结果,可以通过resp.encoding='gbk'来变更解码方式,通俗的来说就是能显示中文
print(resp.text)
从输出的文本内容显示body标签段能获取到我们需要的数据内容:
一、方法一(此方法失败,可直接看方法二,这里仅做记录):
1.从body标签段再具体缩小到div标签段,爬取此标签的数据内容,为分类出所需信息做准备:
# 先导入包
import requests
from bs4 import BeautifulSoup
# 添加header请求头,防止被拦截
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'}
# 获取百度热搜小说榜的地址,以resp对象存储
resp=requests.get("https://top.baidu.com/board?tab=novel",headers=headers)
# 输出一下获取的网站,resp.text是返回headers中的编码解析的结果,可以通过resp.encoding='gbk'来变更解码方式,通俗的来说就是能显示中文
#print(resp.text)
# Beautiful Soup是一个可以从html文件中提取数据的python库,html.parser是转换器
bs=BeautifulSoup(resp.text,"html.parser")
# find查找属性名id和属性内容sanRoot,只找出第一个
sanRoot=bs.find(attrs={"id":"sanRoot"})
print(sanRoot)
结果如下所示(我在文字编辑器中对关键信息做了简单的筛选,因此展现为分行格式):
并且此关键信息是以注释的方式加进去的,解析的时候要解析注释的内容:
2.将div标签段的内容转换为文本形式方便查看
此时我们需要的字段已经在此显示,但是可读性很差,需要自行筛选和分类:
3.替换无关标签字段:
将多余无用的标签字段比如:<div class="wrapper c-font-normal rel" id="sanRoot" theme="novel">用空格替换,虽然可行,但是要替换的标签不仅量大而且杂乱,因此这个方法pass
贴一个老师课上的演示视频:小说榜爬取方法一不足之处-CSDN直播
二、方法二
重新在页面的Response里格式化一下代码,观察页面的代码格式,最后通过所需字段标签的属性内容来定位,逐个爬取相应字段:
import requests
from bs4 import BeautifulSoup
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'}
resp=requests.get("https://top.baidu.com/board?tab=novel",headers=headers)
# print(resp.text)
bs=BeautifulSoup(resp.text,"html.parser")
# 是每一部小说的总标签属性和属性内容
categorywrap_iQLoos=bs.find_all(attrs={"class":"category-wrap_iQLoo"})
# 对总标签属性内容进行遍历,一部小说结束进行一次循环
for categorywrap_iQLoo in categorywrap_iQLoos:
hote=categorywrap_iQLoo.find(name="a", attrs={"class": "trend_2RttY"}).find(name="div",attrs={"class":"hot-index_1Bl1a"}).text
print(" 热度为:"+hote)
name=categorywrap_iQLoo.find(name="div",attrs={"class":"content_1YWBm"}).find(attrs={"class":"c-single-text-ellipsis"}).text
print(" 书名:"+name)
# 因为由标签可知intro_1l0wp属性内容对应两组字符串,要用find_all而不是find,并且可以通过下标标注的形式遍历输出
eles=categorywrap_iQLoo.find(name="div", attrs={"class": "content_1YWBm"}).find_all(attrs={"class":"intro_1l0wp"})
auth=eles[0].text
print(auth) # 作者
print(eles[1].text) # 类型
info=categorywrap_iQLoo.find(name="div", attrs={"class": "content_1YWBm"}).find(attrs={"c-single-text-ellipsis desc_3CTjT"}).text
print(" 说明:"+info)
print("=====================================================================")
爬取结果如下:
以上的爬取结果只是对页面所需数据的简单整合,并没有对字间距等其他影响可读性的内容进行相关优化
后续思考认为不必在爬取时连续用两个find,只需在整体的属性内容下定位到字段直接对应的属性内容:
hote=categorywrap_iQLoo.find(name="div",attrs={"class":"hot-index_1Bl1a"}).text
print(" 热度为:"+hote)
name=categorywrap_iQLoo.find(attrs={"class":"c-single-text-ellipsis"}).text
print(" 书名:"+name)
eles = categorywrap_iQLoo.find_all(attrs={"class": "intro_1l0wp"})
auth = eles[0].text
print(auth)
print(eles[1].text)
info = categorywrap_iQLoo.find(attrs={"c-single-text-ellipsis desc_3CTjT"}).text
print(" 说明:" + info)
最后贴一个老师转换思路之后的爬取视频讲解: