• Python爬取笔趣阁小说
Never really desperate, only the lost of the soul     
  • Python爬取笔趣阁小说


写在前面:心血来潮,突然想去爬个小说看看,就选笔趣阁吧,以前看小说都是在这里看的,看了下小说排行榜,《斗罗大陆3龙王传说》排行第一,那就拿你试试

分析网页

进入小说主页,发现小说的所有章节列表都给列举出来了

检查一下页面结构,发现所有章节列表信息都放在dd标签下的a标签中,而href属性中则储存类似11396140.html这样的HTML后缀,盲猜这是每个章节内容页面的URL后缀,点开一个章节看看:

果不其然,每个章节页面的URL分为两部分,前面部分:https://www.52bqg.com/book_27833/ 就是小说主页地址,后面部分:11396140.html就是每个章节列表a标签href属性中存储的HTML后缀。这样的话就简单多了,爬取思路如下:

  • 1.爬取每个章节名字和HTML后缀,存入一个字典中
  • 2.遍历字典中每一个元素,分别在每个章节页面提取所需内容
  • 3.在遍历的过程中顺便进行数据持久化,存储数据到txt文件中

爬取章节列表数据

首先引入所需模块

import requests
import time
from lxml import etree

然后请求小说主页

url = 'https://www.52bqg.com/book_27833/'
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"}
res = requests.get(url,headers = headers)
res.encoding = 'gbk'
html = etree.HTML(res.text)
title_list = html.xpath('//*[@id="list"]/dl/dd/a/text()')
name = html.xpath('//*[@id="info"]/h1/text()')[0]
url_list = html.xpath('//*[@id="list"]/dl/dd/a/@href')
data = dict(zip(title_list,url_list))

使用xpath选择器,将小说名字提取出来,用于命名后面的小说txt文件,
然后将小说章节名字和HTML后缀保存在data这个字典中,打印出来看看:

这一步目标已经完成

爬取每个章节内容

这里请求第一章页面

r_url = 'https://www.52bqg.com/book_27833/11396151.html'
res1 = requests.get(r_url,headers = headers)
res1.encoding = 'gbk'
cha_html = etree.HTML(res1.text)
content = cha_html.xpath('//*[@id="content"]/text()')
print(content)

看看打印结果:

可以看到,结果是一个列表,列表中的每一个元素则是小说内容的每一个段落,这里遍历输出一下列表元素来看看:

嗯还比较美观,这样的话就可以以这样的形式,将小说内容写入txt文件了

下载小说内容

按照上面的方式,遍历每个章节内容段落列表,将列表中的每个元素写入txt文件中

def download(f,cha_name,content):
    f.write('\n' + cha_name + '\n')
    for item in content:
        f.write(item)

其中参数f是小说文件,cha_name是每个章节的名字,content则是需要遍历的段落列表

主函数

def main():
    data = get_data(url)
    data_dict = data[0]
    name = data[1]
    print(name)
    f = open(name + '.txt','w',encoding='utf-8')
    for kv in data_dict.items():
        time.sleep(3)
        try:
            content = get_content(url + kv[1])
            download(f,kv[0],content)
            print('下载成功:' + kv[0])
        except:
            print('下载失败:' + kv[0])
    f.close() 

为了避免请求过于频繁,这里使用time库设置了3s的请求周期

最后

看看程序运行结果:

完整代码如下:

import requests
import time
from lxml import etree

url = input("请输入笔趣阁(52bqg.com)小说主页URL:")
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"}

def get_data(url):
    res = requests.get(url,headers = headers)
    res.encoding = 'gbk'
    html = etree.HTML(res.text)
    title_list = html.xpath('//*[@id="list"]/dl/dd/a/text()')
    url_list = html.xpath('//*[@id="list"]/dl/dd/a/@href')
    name = html.xpath('//*[@id="info"]/h1/text()')[0]
    data = dict(zip(title_list,url_list))
    return data,name

def get_content(url):
    res1 = requests.get(url,headers = headers)
    res1.encoding = 'gbk'
    cha_html = etree.HTML(res1.text)
    content = cha_html.xpath('//*[@id="content"]/text()')
    return content

def download(f,cha_name,content):
    f.write('\n' + cha_name + '\n')
    for item in content:
        f.write(item)

def main():
    data = get_data(url)
    data_dict = data[0]
    name = data[1]
    print(name)
    f = open(name + '.txt','w',encoding='utf-8')
    for kv in data_dict.items():
        time.sleep(3)
        try:
            content = get_content(url + kv[1])
            download(f,kv[0],content)
            print('下载成功:' + kv[0])
        except:
            print('下载失败:' + kv[0])
    f.close()    
if __name__ == '__main__':
    main()

说些什么吧

  关于博主
https://file.ztongyang.cn/yang/picttures/QQqr.jpg https://file.ztongyang.cn/yang/picttures/wechatqr.png http://metu.ztongyang.cn/a/avatar.jpg avatar

南玖

生命不息,折腾不止

  网站咨询
  •   当前在线1人
  •   加载耗时27 ms
  •   文章数目29篇
  •   分类总数8个
  •   评论总数39条
  •   站点字数3.26 W
  •   运行时间311天