请选择 进入手机版 | 继续访问电脑版

深蓝论坛

搜索
查看: 50|回复: 0

Python爬取小说并写入word文档

[复制链接]

522

主题

4

回帖

2026

积分

管理员

蛮荒网络

Rank: 9Rank: 9Rank: 9

积分
2026

勋章4勋章6冰墩墩滑稽单身狗

发表于 2023-9-2 18:57:18 | 显示全部楼层 |阅读模式
先看效果
image.png

image.png

目标网站结构分析
目标网站就是我们知名的笔趣阁:https://www.biquzw.la/,知名的搬运网站,受众很大,书源也是海量的,主要是没限制的话,好爬!

开头提到的充钱,主要也是搬运工的功劳,与我无关啊。

进入首页,选择我们要爬取的书籍,点进去,刷新页面,确定书籍的url。这里我们可以确定本网站每本书的url是固定的;

image.png

小说概览页

小说详情页,主要是两个部分,一部分是上面的书名、作者、类别等详情信息,另外一部分就是下面的章节信息了;

进一步确认,章节信息全部加载并渲染,所以不用担心获取章节信息的时候还有翻页了。

这里我们还能发现章节相关标签内,还带有一个a标签,点击我们就能发现是对应章的小说内容页。基本可以确定后面获取正文的思路就是获取这个url,进入小说内容页获取正文。

image.png


小说阅读页

小说阅读页,也就是小说的正文内容了,正文内容全部在同一个标签内,所以获取方式也很简单,同时结合上面部分,每个章节的url获取也是非常简单的。


基本就可以确定思路了: 手动获取小说url——>爬取章节名称及其url——>正文获取

环境准备
  1. pip install requests
  2. pip install lxml
  3. pip install docx
  4. # docx包的运行需要依赖python-docx,所以也要安装
  5. pip install python-docx
复制代码

image.png


发送请求获取数据
导入requests包,设置headers字典类型的参数,headers就是上面获取的cookie和user-agent参数;然后设置要爬取的小说的url。

以上就完成了基本的参数设置;

数据的请求,一行代码就完成了,即利用requests下的get方法进行请求即可,将请求结果赋值给response;

至此就完成了网页数据的请求;

将得到的结果response及其类型打印出来,结果如下;

  1. import requests

  2. headers = {
  3.     'Cookie': 'clickbids=116117; Hm_lvt_6dfe3c8f195b43b8e667a2a2e5936122=1675151965,1675218073; Hm_lpvt_6dfe3c8f195b43b8e667a2a2e5936122=1675218073',
  4.     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
  5. }
  6. cata_url = 'https://www.biquzw.la/116_116117/'
  7. response = requests.get(cata_url, headers=headers)
  8. print(response)
  9. print(type(response))

  10. # 输出:
  11. # <Response [200]>
  12. # <class 'requests.models.Response'>
复制代码
  1. response.text  # 响应回去的文本(字符串)
  2. response.content  # 响应回去的内容(二进制),一般用来爬取视频
  3. response.status_code  # 响应的状态码
  4. response.url  # 获取请求连接地址
  5. response.cookies  # 获取返回的cookies信息
  6. response.cookies.get_dict()  # 获取返回的cookies信息
  7. response.request  # 获取请求方式
  8. response.json()  # 将结果进行反序列化
  9. response.apparent_encoding  # 文档的编码的方式(从HTML文档找)
  10. response.encoding  # 响应体编码方式
  11. eg: response.encoding = response.apparent_encoding  # 文档的声明方式
  12. response.headers  # 查看响应头
  13. response.history  # 重定向历史   即前一次请求的地址
复制代码
image.png


获取网页数据
我们要的东西简单直接,就是网页原始文件数据,通过上面这部分的方法,我们直接通过response.text即可获取到网页数据;

但是我们直接打印会发现一个问题,那就是中文乱码;

所以还需要设定一下编码方式
  1. response.encoding = 'utf-8';
复制代码


image.png


提取数据

上面的步骤都还是非常简单的内容,爬虫最麻烦的工作之一就是这里了;

获取到网页数据了,从网页中提取数据的方式很多,常见的有xpath、正则表达式、beautifulsoup等;

具体的还得根据网页的结构来,我们的目标网站结构简单,所以我们直接通过xpath进行获取即可(具体的方式方法后面出文章吧);

要利用xpath解析的话,就需要把网页文本转为html对象;

主要利用的是lxml包;

  1. html = etree.HTML(response.text, parser=etree.HTMLParser(encoding='utf-8'))
  2. i = 1
  3. while True:
  4.     href = html.xpath('//*[@id="list"]/dl/dd[' + str(i) + ']/a/@href')
  5.     title = html.xpath('//*[@id="list"]/dl/dd[' + str(i) + ']/a/@title')
  6.     if len(href):
  7.         print(href, title)
  8.         i = i + 1
  9.     else:
  10.         print("爬取完成")
  11.         break
复制代码



循环获取对应的文字和url:

  1. href = html.xpath('//*[@id="list"]/dl/dd[' + str(i) + ']/a/@href') title = html.xpath('//*[@id="list"]/dl/dd[' + str(i) + ']/a/@title')
复制代码



判断是否正常提取到了文字及url,如果正常就打印并继续循环提取,为空则获取完毕:

  1. if len(href): print(href, title) i = i + 1 content_get(title[0],href[0]) else: print("爬取完成") break
复制代码
image.png



小说内容获取

上面获取到了每个章节的url和标题;

接下来就直接拼接url并获取数据即可;

方法和获取章节信息是相同的,利用requests包请求以及xpath解析即可;

为了配合上面的循环,这里我们将内容获取定义为一个函数:


  1. def content_get(title,url):
  2.     content_url = 'https://www.biquzw.la/116_116117/'
  3.     content_response = requests.get(content_url + url, headers=headers)
  4.     content_response.encoding = 'utf-8'
  5.     html = etree.HTML(content_response.text,parser=etree.HTMLParser(encoding='utf-8'))
  6.     content = html.xpath('//*[@id="content"]/text()')
  7.     for i in range(len(content)):
  8.         print(content[i])
复制代码



在章节获取的循环中调用这个函数即可:content_get(title[0], href[0]);

运行效果:

image.png


写入txt/word文档
写入txt
文本数据一般爬取的话就是写入txt文档,如果有特别的需求也可以写入数据库中去;这里主要记录一下写入的思路和方法;主要写入可以分为两个方式,一个就是全部写入同一个文档,另一个是分章节写入不同的txt,同最开始的效果展示一样。

全部写入一个文档就是在爬虫开始的时候就打开一个文档,在爬虫结束的时候才关闭这个文档;分别写入不同的文档的话,就需要不断的新建文档;

所以二者的代码结构是不同的,但是方法相同,几行代码就能达到我们的目标;

  1. file = open(r'./测试.txt', mode='a', encoding='utf-8')
  2. file.write('## 测试内容 \n')
  3. file.close()
复制代码
image.png


写入word
写入word的思路同样很简单,将标题设置为标题,将文本内容设置为正文;

所以我们知道怎么向word写入标题和正文即可,不需要写入图片以及设置样式啥的,所以还是比较简单的,当然这些也能实现,但是这里没必要么;


  1. # -*- coding: utf-8 -*-
  2. # @Time: 2023/2/1 11:49
  3. # @Author: MinChess
  4. # @File: doc.py
  5. # @Software: PyCharm
  6. import docx

  7. #创建内存中的word文档对象
  8. file=docx.Document()
  9. file.add_heading(text="这是一级标题", level=1)
  10. file.add_paragraph("发发发发发发付付付付付付付")
  11. file.add_heading(text="这是二级标题", level=2)
  12. file.add_paragraph("发发发发发发付付付付付付付付付")

  13. #保存
  14. file.save("./test.docx")

复制代码
image.png

写入txt
  1. # -*- coding: utf-8 -*-
  2. # @Time: 2023/2/1 10:29
  3. # @Author: MinChess
  4. # @File: request.py
  5. # @Software: PyCharm
  6. import requests
  7. from lxml import etree

  8. headers = {
  9.     'Cookie': 'clickbids=116117; Hm_lvt_6dfe3c8f195b43b8e667a2a2e5936122=1675151965,1675218073; Hm_lpvt_6dfe3c8f195b43b8e667a2a2e5936122=1675218073',
  10.     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
  11. }


  12. def catalog_get():
  13.     cata_url = 'https://www.biquzw.la/116_116117/'
  14.     response = requests.get(cata_url, headers=headers)
  15.     response.encoding = 'utf-8'
  16.     # print(response.text)
  17.     html = etree.HTML(response.text, parser=etree.HTMLParser(encoding='utf-8'))
  18.     # print(html)
  19.     i = 1
  20.     while True:
  21.         href = html.xpath('//*[@id="list"]/dl/dd[' + str(i) + ']/a/@href')
  22.         title = html.xpath('//*[@id="list"]/dl/dd[' + str(i) + ']/a/@title')
  23.         if len(href):
  24.             print(href, title)
  25.             i = i + 1
  26.             content_get(title[0],href[0])
  27.         else:
  28.             print("爬取完成")
  29.             break


  30. def content_get(title,url):
  31.     file = open(r'./明克街/'+title+'.txt', mode='a', encoding='utf-8')
  32.     file.write('## ' + title + '\n')
  33.     content_url = 'https://www.biquzw.la/116_116117/'
  34.     content_response = requests.get(content_url + url, headers=headers)
  35.     content_response.encoding = 'utf-8'
  36.     # print(content_response.text)
  37.     html = etree.HTML(content_response.text,parser=etree.HTMLParser(encoding='utf-8'))
  38.     content = html.xpath('//*[@id="content"]/text()')
  39.     # a_res = etree.tostring(content[0], encoding='utf-8').strip().decode('utf-8')
  40.     # print(a_res)
  41.     # print(content)
  42.     for i in range(len(content)):
  43.         # print(content[i])
  44.         file.write(content[i]+'\n')
  45.     file.close()


  46. if __name__ == '__main__':
  47.     catalog_get()
复制代码


写入word
  1. # -*- coding: utf-8 -*-
  2. # @Time: 2023/2/8 17:47
  3. # @Author: MinChess
  4. # @File: reword.py
  5. # @Software: PyCharm
  6. import requests
  7. from lxml import etree
  8. import docx

  9. headers = {
  10.     'Cookie': 'clickbids=116117; Hm_lvt_6dfe3c8f195b43b8e667a2a2e5936122=1675151965,1675218073; Hm_lpvt_6dfe3c8f195b43b8e667a2a2e5936122=1675218073',
  11.     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
  12. }

  13. file = docx.Document()

  14. def catalog_get():

  15.     cata_url = 'https://www.biquzw.la/116_116117/'
  16.     response = requests.get(cata_url, headers=headers)
  17.     response.encoding = 'utf-8'
  18.     html = etree.HTML(response.text, parser=etree.HTMLParser(encoding='utf-8'))
  19.     i = 1
  20.     while True:
  21.         href = html.xpath('//*[@id="list"]/dl/dd[' + str(i) + ']/a/@href')
  22.         title = html.xpath('//*[@id="list"]/dl/dd[' + str(i) + ']/a/@title')
  23.         if len(href):
  24.             print(href, title)
  25.             i = i + 1
  26.             content_get(title[0],href[0])
  27.         else:
  28.             print("爬取完成")
  29.             file.save("./mkj.docx")
  30.             break


  31. def content_get(title,url):
  32.     file.add_heading(text=title, level=1)
  33.     content_url = 'https://www.biquzw.la/116_116117/'
  34.     content_response = requests.get(content_url + url, headers=headers)
  35.     content_response.encoding = 'utf-8'
  36.     html = etree.HTML(content_response.text,parser=etree.HTMLParser(encoding='utf-8'))
  37.     content = html.xpath('//*[@id="content"]/text()')
  38.     for i in range(len(content)):
  39.         # print(content[i])
  40.         file.add_paragraph(content[i])



  41. if __name__ == '__main__':
  42.     catalog_get()
复制代码

大牛马一个
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表