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 爬取网页时文本乱码解决办法