Python爬虫学习第三章-3.2-bs4实战:爬取三国演义小说的章节标题和内容
这一节主要是用bs4爬取三国演义小说的章节标题和内容
首页中提供个每个章节的标题,章节标题对应的是一个a标签(因为可以点击),点击标题就可以进入详情页,所以我们要爬取的是首页当中的标题和每个详情页中的内容。
思路:
- 先使用通用爬虫爬取首页的数据,解析出首页中包含的所有的章节的标题和每个标题对应的a标签中的href属性值,这个属性值就是标题所对应的详情页的url;
- 再根据详情页的url发送请求,就可以拿到详情页对应的页面数据,最后提取出文本内容即可。
代码设计流程:
- 先指定首页的url,进行UA伪装(其实UA伪装可以放在最前面),然后发送get请求,通过text属性获取首页的响应数据page_text,从响应的数据中利用BeautifulSoup解析数据,获取章节的标题和详情页的url。
- BeautifulSoup解析的流程:
- 先用soup = BeautifulSoup(page_text,‘lxml’)实例化一个BeautifulSoup对象,将页面源码数据加载到该对象中,参数一是要加载的源码数据,在这里就是我们从首页获取的响应数据page_text;然后解析章节标题和详情页的url:由源代码可以发现,章节标题在div标签的li标签的a标签中,同时,a标签的href属性值就是我们所需要的详情页的url。
- 下一步就是批量获取li标签中的a标签。用soup.select(’.book-mulu > ul > li’)返回存放li标签的列表li_list,再从每一个li标签中获取a标签即li.a,并进一步利用title = li.a.string 和detail_url = ‘https://www.shicimingju.com’+li.a[‘href’]来获取a标签中章节标题href属性。
- 再对每一个详情页的url发送请求,获取详情页中的数据detail_page_text。
- 再次利用BeautifulSoup进行数据解析,detail_soup = BeautifulSoup(detail_page_text,‘lxml’),通过观察源代码,可以发现段落信息都在div标签中,所以可以通过div_tag = detail_soup.find(‘div’,class_=‘chapter_content’)获得标签内容,再用content = div_tag.text得到章节的内容。
- 最后持久化存储即可,
fp = open('./sanguo.txt','w',encoding='utf-8')
fp.write(title+':'+content+'\n')
代码实现:
#需求:爬取三国演小说的所有章节标题和章节内容 https://www.shicimingju.com/book/sanguoyanyi.html
# 思路:先使用通用爬虫爬取整张页面,再进行数据解析获取标题和章节所对应的链接的地址,再通过获取的详情页的链接获取每个章节的数据,
import requests
from bs4 import BeautifulSoup
if __name__=="__main__":
#对首页的页面数据进行爬取
url = 'https://www.shicimingju.com/book/sanguoyanyi.html'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36'
}
#发起请求并获取数据
page_text = requests.get(url = url,headers = headers).text
#在首页中解析出标题和详情页的url
#1、实例化一个BeautiSoup对象,需要将总页面源码数据加载到该对象中
soup = BeautifulSoup(page_text,'lxml')
#解析章节标题和详情页的url
li_list = soup.select('.book-mulu > ul > li') #返回的是存放一系列li标签的列表
fp = open('./sanguo.txt','w',encoding='utf-8')
for li in li_list:
#在主页面中每一个标题都可以点击,说明标题存在于a标签内
title = li.a.string #获取li标签中的a标签中的字符串
detail_url = 'https://www.shicimingju.com'+li.a['href'] #完整的详情页的url
#对详情页发起请求,解析出章节内容
detail_page_text = requests.get(url = detail_url,headers = headers).text #获取详情页对应的数据
#从detail_page_text中解析出章节内容
detail_soup = BeautifulSoup(detail_page_text,'lxml')
div_tag = detail_soup.find('div',class_='chapter_content')
#解析到了章节的内容
content = div_tag.text
fp.write(title+':'+content+'\n')
print(title,'爬取成功')
前几天一位小伙伴评论说出现了乱码,我找了写资料,改了一下,把page_text = requests.get(url = url,headers = headers).text
改为:html = requests.get(url = url,headers = headers);html.encoding = 'UTF-8';page_text = html.text;
就欧克了
或者是在html = requests.get(url = url,headers = headers)
后面加一句:response = bytes(html.text, html.encoding).decode('utf-8', 'ignore')
也在这里谢谢他的指正(手动送花)。
注意在for循环中也要做相同的操作。
修改后的代码如下:
#需求:爬取三国演小说的所有章节标题和章节内容 https://www.shicimingju.com/book/sanguoyanyi.html
# 思路:先使用通用爬虫爬取整张页面,再进行数据解析获取标题和章节所对应的链接的地址,再通过获取的详情页的链接获取每个章节的数据,
import requests
from bs4 import BeautifulSoup
if __name__=="__main__":
#对首页的页面数据进行爬取
url = 'https://www.shicimingju.com/book/sanguoyanyi.html'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36'
}
#发起请求并获取数据
html = requests.get(url = url,headers = headers)
# 解决乱码问题的方案一:
response = bytes(html.text, html.encoding).decode('utf-8', 'ignore')
# 解决乱码问题的方案二:
# html.encoding = 'UTF-8'
# response = html.text
# 注意要在下面的for循环中做相同原理的操作
#在首页中解析出标题和详情页的url
#1、实例化一个BeautiSoup对象,需要将总页面源码数据加载到该对象中
soup = BeautifulSoup(response,'lxml')
#解析章节标题和详情页的url
li_list = soup.select('.book-mulu > ul > li') #返回的是存放一系列li标签的列表
fp = open('./sanguo.txt','w',encoding='utf-8')
for li in li_list:
#在主页面中每一个标题都可以点击,说明标题存在于a标签内
title = li.a.string #获取li标签中的a标签中的字符串
detail_url = 'https://www.shicimingju.com'+li.a['href'] #完整的详情页的url
#对详情页发起请求,解析出章节内容
detail_page_text = requests.get(url = detail_url,headers = headers)#获取详情页对应的数据
detail_page_text_response = bytes(detail_page_text.text, html.encoding).decode('utf-8', 'ignore')
#从detail_page_text中解析出章节内容
detail_soup = BeautifulSoup(detail_page_text_response,'lxml')
div_tag = detail_soup.find('div',class_='chapter_content')
#解析到了章节的内容
content = div_tag.text
fp.write(title+':'+content+'\n')
print(title,'爬取成功')
我感觉这篇文章挺好的,安利一下:
Python 爬虫使用Requests获取网页文本内容中文乱码 这篇也挺管用的:
python 爬取网页时文本乱码解决办法