ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

爬虫实战(六):爬笔趣阁小说

2022-07-06 18:02:48  阅读:173  来源: 互联网

标签:实战 url text resp 爬虫 content re print 笔趣


目录

爬虫实战(六):爬笔趣阁

一、 网站分析

1、 页面分析

通过抓包分析可以得到,该网站为静态网站,所有信息都保存在页面源码中,可以直接从页面源码获取信息。

在目录中,发现其全部存储在一个dl的标签中

在搜索目录中,搜索内容存储在一个列表中,我们可以通过获取列表的长度来知道是否查找到了结果;如果没有搜索到结果,则不会将列表哦渲染出来,我们可以通过<div class="novelslistss"></div>来判断是否查找成功

2、 源码分析

通过分析源码,发现,目录包裹在<dl></dl>,内容包裹在一个<div id="content"></div>

3、 链接分析

# 通过几次搜索可以得到几个url
# https://www.bqg.org/modules/article/search.php?searchkey=%BE%F8%CA%C0%CE%E4%C9%F1 # 绝世武神
# https://www.bqg.org/modules/article/search.php?searchkey=%BE%F8%CA%C0%CC%C6%C3%C5 # 绝世唐门
url = "https://www.bqg.org/modules/article/search.php?searchkey=%s"
from urllib import parse
print(parse.quote("绝世武神".encode("gbk")))  
# 在多次尝试下,发现,其先是对文本内容进行gbk编码,再进行url编码
# 故,我们可以模拟搜索工具,来对内容进行精确的查找

name = input("请输入书名:")  # 获取用户输入的书名
print(url % parse.quote(name.encode("gbk")))  # 得到url

二、 编写代码

1、 获取目录

# !/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "biquge.py"
__time__ = "2022/7/6 14:03"
# 导入必要的模块
import requests, re  # 发送请求,使用正则获取全部内容
from urllib import parse  # 进行书名的编码
from fake_useragent import UserAgent  # UA伪装

# 这次获取的是风起龙城的目录

url = "https://www.bqg.org/53_53985/"  # 要爬取的url
headers = {
    'Accept': ' text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Accept-Encoding': ' gzip, deflate, br',
    'Accept-Language': ' zh-CN,zh;q=0.9',
    'Cache-Control': ' no-cache',
    'Connection': ' keep-alive',
    'Cookie': ' jieqiVisitId=article_articleviews%3D53982; jieqiVisitTime=jieqiArticlesearchTime%3D1657088500; clickbids=53982',
    'Host': ' www.bqg.org',
    'Pragma': ' no-cache',
    'Referer': ' https://www.bqg.org/',
    'sec-ch-ua': ' " Not A;Brand";v="99", "Chromium";v="102", "Google Chrome";v="102"',
    'sec-ch-ua-mobile': ' ?0',
    'sec-ch-ua-platform': ' "Windows"',
    'Sec-Fetch-Dest': ' document',
    'Sec-Fetch-Mode': ' navigate',
    'Sec-Fetch-Site': ' same-origin',
    'Sec-Fetch-User': ' ?1',
    'Upgrade-Insecure-Requests': ' 1',
    'user-agent': UserAgent().random
}
def get_menu(url):
    headers.update({'user-agent': UserAgent().random})  # 随机请求头
    resp = requests.get(url, headers)  # 发起请求
    resp.encoding = resp.apparent_encoding  # 要文件的编码应该为gbk
    temp = re.search("正文.*?</dl>", resp.text).group()  # 进行剪切,去除开头那新更新的目录
    lis = re.findall(r'<a href="(.*?)">(.*?)</a>', temp)  # 使用正则获取到目录和对应目录的链接
    url_de = []
    chapters = []
    for i in lis:
        url_de.append(f"{url}{i[0]}")
        chapters.append(i[1])
    # print(url_de, chapters)
    return url_de, chapters  # 返回结果

get_menu(url)

2、 访问目录

def get_content(url):
    headers.update({'user-agent': UserAgent().random})  # 随机请求头
    resp = requests.get(url, headers)  # 获取响应
    resp.encoding = resp.apparent_encoding  # 编码
    content = re.search('<div id="content" name="content">(?P<content>.*?)</div>', resp.text, re.S).group("content")  # 获取到内容
    content = re.sub(r'<br.*?>', "\n", content)  # 使用正则替换清洗数据
    content = re.sub(r'&nbsp;', " ", content)  # 使用正则替换清洗数据
    return content  # 返回结果
    
    
get_content("https://www.bqg.org/53_53985/38645272.html")  # 测试使用

3、 下载数据

def save_data(url_):
    with open("./风起龙城.txt", "w", encoding="utf-8") as f:
        urls, menus = get_menu(url_)
        for index, url in enumerate(urls):
            f.write(f"==============={menus[index]}===============\n")
            print(f"正在下载:{menus[index]}")
            content = get_content(url)
            f.write(content + "\n")
            print(f"{menus[index]},下载完成")
        
save_data("https://www.bqg.org/53_53985/")

4、 搜索功能

url = "https://www.bqg.org/modules/article/search.php?searchkey=%s"
from lxml import etree
from prettytable import PrettyTable


def have_content(text):
    # 当查找到内容时,展示查找到的内容给用户选择
    html = etree.HTML(text)
    li_s = html.xpath("//*[@id='main']/div[1]/li")
    table = PrettyTable(['序号',"类型", '书名','作者'])
    lis_ = []
    index = 0
    for index, li in enumerate(li_s):
        type_ = li.xpath("./span[@class='s1']/text()")
        name = li.xpath("./span[@class='s2']/a/text()")
        url = li.xpath("./span[@class='s2']/a/@href")
        lis_.append(url)
        author = li.xpath("./span[@class='s4']/text()")
        table.add_row([index + 1,type_, name, table])
    
    print(table)
    i = input("请输入要下载的序号:")
    if i < index and i > 0:
        return lis_[i - 1]
    print("请按要求输入哦!")
    

def search(n):
    arg = parse.quote(n.encode("gbk"))
    headers.update({'user-agent': UserAgent().random})  # 随机请求头
    resp = requests.get(url % arg, headers)  # 发起请求
    resp.encoding = resp.apparent_encoding  # 设置当前编码
    tet = resp.text  # 获取内容
    if re.search("错误原因:对不起,没有搜索.*?文章!", tet):
        print("对不起,没有搜索到您要的文章!")
        return
    if re.search("错误原因:对不起,两次搜索.*?秒", tet):
        print("对不起,两次搜索的间隔时间不得少于30秒")
        return 
    # 剩下的都是查到内容的
    have_content(tet)  # 获取具体的下载名

    
name = input("请输入要下载的小说:")
search(name)

三、 总代码

# !/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "biquge.py"
__time__ = "2022/7/6 14:03"
# 导入必要的模块
import requests, re, sys  # 发送请求,使用正则获取全部内容
from urllib import parse  # 进行书名的编码
from fake_useragent import UserAgent  # UA伪装

url = "https://www.bqg.org/modules/article/search.php?searchkey=%s"  # 查找的url
headers = {
    'Accept': ' text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Accept-Encoding': ' gzip, deflate, br',
    'Accept-Language': ' zh-CN,zh;q=0.9',
    'Cache-Control': ' no-cache',
    'Connection': ' keep-alive',
    'Cookie': ' jieqiVisitId=article_articleviews%3D53982; jieqiVisitTime=jieqiArticlesearchTime%3D1657088500; clickbids=53982',
    'Host': ' www.bqg.org',
    'Pragma': ' no-cache',
    'Referer': ' https://www.bqg.org/',
    'sec-ch-ua': ' " Not A;Brand";v="99", "Chromium";v="102", "Google Chrome";v="102"',
    'sec-ch-ua-mobile': ' ?0',
    'sec-ch-ua-platform': ' "Windows"',
    'Sec-Fetch-Dest': ' document',
    'Sec-Fetch-Mode': ' navigate',
    'Sec-Fetch-Site': ' same-origin',
    'Sec-Fetch-User': ' ?1',
    'Upgrade-Insecure-Requests': ' 1',
    'user-agent': UserAgent().random
}



def have_content(text):
    # 当查找到内容时,展示查找到的内容给用户选择
    html = etree.HTML(text)
    li_s = html.xpath("//*[@id='main']/div[1]/li")
    table = PrettyTable(['序号',"类型", '书名','作者'])
    lis_ = []
    index = 0
    for index, li in enumerate(li_s):
        type_ = li.xpath("./span[@class='s1']/text()")[0]
        name = li.xpath("./span[@class='s2']/a/text()")[0]
        url = li.xpath("./span[@class='s2']/a/@href")[0]
        lis_.append(url)
        author = li.xpath("./span[@class='s4']/text()")[0]
        table.add_row([index + 1,type_, name, table])
    
    print(table)
    i = input("请输入要下载的序号:")
    if i <= index and i > 0:
        return lis_[i - 1]
    print("请按要求输入哦!")
    sys.exit(0)
    

def search(n):
    arg = parse.quote(n.encode("gbk"))
    headers.update({'user-agent': UserAgent().random})  # 随机请求头
    resp = requests.get(url % arg, headers)  # 发起请求
    resp.encoding = resp.apparent_encoding  # 设置当前编码
    tet = resp.text  # 获取内容
    if re.search("错误原因:对不起,没有搜索.*?文章!", tet):
        print("对不起,没有搜索到您要的文章!")
        return
    if re.search("错误原因:对不起,两次搜索.*?秒", tet):
        print("对不起,两次搜索的间隔时间不得少于30秒")
        return 
    # 剩下的都是查到内容的
    return have_content(tet)  # 获取具体的下载名,并且把url返回

def get_menu(url):
    headers.update({'user-agent': UserAgent().random})  # 随机请求头
    resp = requests.get(url, headers)  # 发起请求
    resp.encoding = resp.apparent_encoding  # 要文件的编码应该为gbk
    temp = re.search("正文.*?</dl>", resp.text).group()  # 进行剪切,去除开头那新更新的目录
    lis = re.findall(r'<a href="(.*?)">(.*?)</a>', temp)  # 使用正则获取到目录和对应目录的链接
    url_de = []
    chapters = []
    for i in lis:
        url_de.append(f"{url}{i[0]}")
        chapters.append(i[1])
    # print(url_de, chapters)
    return url_de, chapters  # 返回结果


def get_content(url):
    headers.update({'user-agent': UserAgent().random})  # 随机请求头
    resp = requests.get(url, headers)  # 获取响应
    resp.encoding = resp.apparent_encoding  # 编码
    content = re.search('<div id="content" name="content">(?P<content>.*?)</div>', resp.text, re.S).group("content")  # 获取到内容
    content = re.sub(r'<br.*?>', "\n", content)  # 使用正则替换清洗数据
    content = re.sub(r'&nbsp;', " ", content)  # 使用正则替换清洗数据
    return content  # 返回结果

def save_data(url_, name):
    with open(f"./{name}.txt", "w", encoding="utf-8") as f:
        urls, menus = get_menu(url_)  # 获取目录信息
        for index, url in enumerate(urls):  # 遍历链接
            f.write(f"==============={menus[index]}===============\n")
            print(f"正在下载:{menus[index]}")
            content = get_content(url)  # 获取详细信息
            f.write(content + "\n")  # 写入文件
            print(f"{menus[index]},下载完成")  # 提示信息
            print("--------------------------")
    
            
def main():
    name = input("请输入要下载的小说名:")
    save_data(search(name), name)
    print("下载完成")
    
if __name__ == "__main__":
    main()

标签:实战,url,text,resp,爬虫,content,re,print,笔趣
来源: https://www.cnblogs.com/liuzhongkun/p/16451858.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有