首页 > 编程语言 >《从零开始学习Python爬虫:顶点小说全网爬取实战》

《从零开始学习Python爬虫:顶点小说全网爬取实战》

时间:2024-07-06 16:41:48浏览次数:21  
标签:chapter xpath get Python 爬虫 爬取 url book page

顶点小说

装xpath helper

GitHub - mic1on/xpath-helper-plus: 这是一个xpath开发者的工具,可以帮助开发者快速的定位网页元素。

Question:加载完插件点击没反应

Answer:将开发人员模式关闭即可

image-20240706100440880

爬虫介绍

分类:

  • 搜索引擎:爬取范围广
  • 聚焦爬虫:爬取范围聚焦

介绍:

程序发起请求(request),获取响应(response),解析response中的数据

URL

即统一资源定位符

组成:

  • 协议
    • http
    • https:新增SSL协议(证书验证),之前花钱,现在开源了,所以大部分网站都是https,据说性能损耗,但忽略不计
  • 主机IP地址(有时也包括端口号)
  • 主机资源具体地址:如目录和文件名等

静态网站和动态网站

  1. 静态网站:数据在页面源代码中
  2. 动态网站:数据在接口中,网站通过ajax请求接口获取数据,再通过js镶在页面中

结构化与非结构化数据

  1. 结构化数据:可以用关系型数据库表示和存储,表现为二维形式的数据
  2. 非结构化数据:数据结构不规则,不方便用二位逻辑来表现,如办公文档、图片、HTML、音频和视频等等

xpath

概念:即为XML路径语言(XML Path Language),用于确定XML文档中某部分位置的语言,python可以使用xpath的语法定位html文档中某部分的位置,并进行抽取

示例:xpath是抽取静态网站数据的常用方法

Question:动态网站可以用xpath进行解析吗?

Answer:

动态网站采用了ajax技术,ajax发起请求对页面进行替换分为 整块替换和 部分替换,部分替换则接口返回数据格式为Json,整块替换则接口返回html文档

如果返回html文档,则可用xpath进行解析,如果返回Json数据,则不可用xpath进行解析

总结:xpath是否可进行解析取决于数据是否为结点数据(是否具有结点),JSON为字符串,肯定不可用xpath进行解析

语法:

  • /:从文档根目录开始选取
  • //:全局进行查找选取,//代表前面有东西,但不重要,相当于正则表达式的 .*?
  • //li/a/text():可以获取小说的所有书名,然后通过python进行切片获取具体的个别数据
  • //li//text():可以获取 li 标签下的所有文字(不区分什么标签),只限深度为1
  • //a[@class="poptext"]:可以选取带有 class属性 的 a标签
  • @href:可以获取此元素的 href属性值
  • *:匹配任何元素结点,如//*、/bookstore/*
  • |:类似and,都获取,如//book/title | //book/price

案例:顶点小说抓取

  1. 导包,定义headers(有的小说网站对headers无要求,有的有要求)
    import requests
    from lxml import etree
    import pymysql
    
    # headers
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0"
    }
    
  2. 获取小说分类url
    # 获取小说分类url
    def get_type():
        url = "https://www.cdbxs.com/sort/"
        source = requests.get(url=url, headers=headers).content.decode('utf-8')
        href_lists = etree.HTML(source).xpath('//ul[@class="nav"]/li/a/@href')[2:-4]
        type_lists = []
        for href in href_lists:
            type_lists.append(f"{url}{href.split('/')[2]}/1/")
        # print(type_lists)
        return type_lists
    
  3. 获取最大页
    # 获取最大页
    def get_max_page(first_page_url):
        source = requests.get(url=first_page_url, headers=headers).content.decode('utf-8')
        # print(source)
        max_page = etree.HTML(source).xpath('//a[13]/text()')
        return max_page
    
  4. 获取每个分类的每一页url
    # 获取小说分类url
    type_lists = get_type()
    # 分类url默认为第一页
    for first_page_url in type_lists:
        # 获取带分类的url的前半截
        type_url = first_page_url.split('1')[0]
        # 获取此分类下最大页
        max_page = get_max_page(first_page_url)
        # 生成此分类下每一页url
        for every_page in range(1, int(max_page[0])+1):
            every_page_url = f"{type_url}{every_page}/"
            print(every_page_url)
    
  5. 获取小说列表页信息
    def get_book_info(every_page_url):
        source = requests.get(url=every_page_url, headers=headers).content.decode('utf-8')
        book_lists = []
    
        lis = etree.HTML(source).xpath("//ul[@class='txt-list txt-list-row5']/li")
        for li in lis:
            book_id_url = li.xpath("span[@class='s2']/a/@href")[0]
            book_id = book_id_url.split('/')[3]
            # 书名
            book_name = li.xpath("span[@class='s2']/a/text()")[0]
            # 最新章节
            new_chapter = li.xpath("span[@class='s3']/a/text()")[0]
            # 作者
            author = li.xpath("span[@class='s4']/text()")[0]
            # 更新时间
            update_time = li.xpath("span[@class='s5']/text()")[0]
    
            source = requests.get(url=f"https://www.cdbxs.com{book_id_url}", headers=headers).content.decode('utf-8')
            # 字数
            font_num = etree.HTML(source).xpath("//p[6]/span/text()")[0]
            # 摘要
            summary = etree.HTML(source).xpath("//div[@class='desc xs-hidden']/text()")[0]
    
            # 以元组添加至 book_lists
            # print((book_id, book_name, new_chapter, author, update_time, font_num, summary))
            book_lists.append((book_id, book_name, new_chapter, author, update_time, font_num, summary))
        return book_lists
    
  6. 获取章节列表url
    # 获取章节列表url
    def get_chapter_urls(chapter_list_url):
        source = requests.get(url=chapter_list_url, headers=headers).content.decode('utf-8')
        # 章节url
        chapter_urls = map(lambda x: "https://www.cdbxs.com" + x, etree.HTML(source).xpath("//div[@class='section-box'][2]/ul[@class='section-list fix']/li/a/@href | //div[@class='section-box'][1]/ul[@class='section-list fix']/li/a/@href"))
    
        return chapter_urls
    
  7. 获取章节详情信息
    # 获取章节详情信息
    def get_chapter_info(chapter_url):
        source = requests.get(url=chapter_url, headers=headers).content.decode('utf-8')
        # 标题
        title = etree.HTML(source).xpath("//h1[@class='title']/text()")
        # 正文
        content = ''.join(etree.HTML(source).xpath("//div[@id='nb_content']/dd//text()"))
        if title:
            return title[0], content
        else:
            return '', content
    
  8. 整合
    # 获取小说分类url
    type_lists = get_type()
    # 分类url默认为第一页
    for first_page_url in type_lists:
        # 获取带分类的url的前半截
        type_url = first_page_url.split('1')[0]
        # 获取此分类下最大页
        max_page = get_max_page(first_page_url)
        # 生成此分类下每一页url
        for every_page in range(1, int(max_page[0]) + 1):
            every_page_url = f"{type_url}{every_page}/"
            # 获取小说列表页信息
            book_info_lists = get_book_info(every_page_url)
            # 获取章节列表url
            for book_info in book_info_lists:
                print(f"爬取小说:{book_info[1]}...")
                book_id = book_info[0]
                chapter_urls = get_chapter_urls(f"https://www.cdbxs.com/booklist/b/{book_id}/1")
                for chapter_url in chapter_urls:
                    # print(chapter_url)
                    chapter_info = get_chapter_info(chapter_url)
                    print(chapter_info)
                    print(chapter_info[0])
                    print(chapter_info[1])
                    # print(f"title:{chapter_info[0]}")
                    # print(f"content:{chapter_info[1]}")
    

:关注我,后续会陆续出爬虫内容(包括但不仅限于顶点小说进阶:数据入库、多线程多进程爬取数据)

更多精致内容,关注公众号:[CodeRealm]

标签:chapter,xpath,get,Python,爬虫,爬取,url,book,page
From: https://www.cnblogs.com/CodeRealm/p/18287439

相关文章

  • Python OS模块操作文件
    在Python中,可以使用os模块主要对文件进行重命名,删除等一些操作以下为os模块常用的方法示例:重命名操作importosos.rename('Test.txt','Test_重命名.txt')#参数1:要重命名的源文件#参数2:对源文件要重新命名的名称删除文件importosos.remove('Test_重命名.tx......
  • 【Python实战因果推断】23_倾向分3
    目录PropensityScoreMatchingInversePropensityWeightingPropensityScoreMatching另一种控制倾向得分的常用方法是匹配估计法。这种方法搜索具有相似可观测特征的单位对,并比较接受干预与未接受干预的单位的结果。如果您有数据科学背景,您可以将匹配视为一种简单的......
  • Python统计实战:时间序列分析之二阶曲线预测和三阶曲线预测
    为了解决特定问题而进行的学习是提高效率的最佳途径。这种方法能够使我们专注于最相关的知识和技能,从而更快地掌握解决问题所需的能力。(以下练习题来源于《统计学—基于Python》。请在Q群455547227下载原始数据。)练习题下表是某只股票连续35个交易日的收盘价格(前3行和后3行......
  • Python统计实战:时间序列分析之一元线性回归预测和指数曲线预测
    为了解决特定问题而进行的学习是提高效率的最佳途径。这种方法能够使我们专注于最相关的知识和技能,从而更快地掌握解决问题所需的能力。(以下练习题来源于《统计学—基于Python》。请在Q群455547227下载原始数据。)练习题下表是某只股票连续35个交易日的收盘价格(前3行和后3行......
  • VB 爬虫技术
    《VB爬虫第一节:初识爬虫》在这第一节的VB爬虫课程中,我们将踏入一个充满挑战与机遇的领域——网络爬虫。一、什么是爬虫爬虫,简单来说,就是一个能够自动获取网页数据的程序。它模拟了人类在浏览器中的操作,通过发送请求、接收响应,并对返回的数据进行解析和提取,从而获取我们......
  • python-docx库 写入docx时中文不适配问题,中文异常问题解决办法。
    python-docx库写入docx时中文不适配问题,中文异常问题解决办法。通过以下方法可以成功将正文修改为宋体字体。这个是全文设置。fromdocx.oxml.nsimportqndoc=Document()doc.styles['Normal'].font.name=u'宋体'doc.styles['Normal']._element.rPr.rFonts.set(qn('w:......
  • 使用Python绘制甘特图
    使用Python绘制甘特图甘特图效果代码甘特图甘特图是一种项目管理工具,用于展示项目进度和任务安排。它通过条状图形表示各任务的起止时间,便于直观地查看项目的各个任务的进度和相互关系。效果[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(im......
  • 十分钟学习Python异常处理
    十分钟学习Python异常处理在编程过程中,错误和异常是不可避免的。Python提供了强大的异常处理机制,帮助我们捕获和处理运行时错误,使程序更加健壮和可靠。本文将带你在十分钟内快速掌握Python的异常处理基础知识。1.什么是异常?异常是指在程序运行过程中发生的错误,它会中断程序......
  • 一个基于Flask框架的Python Web应用程序
    dashboard.py主要实现了以下功能:1.用户注册与登录:提供了用户注册和登录的功能,用户的密码会被哈希处理后存储在users.json文件中。2.文件管理:实现了简单的文件管理功能,包括列出文件夹中的文件、上传文件和删除文件。只有管理员用户才能进行文件管理操作。3,路由定义:定义了......
  • 【python数据挖掘案列】利用线性回归(LR)实现天气变化的时间序列预测
    利用线性回归实现天气变化的时间序列预测一、引言天气预测一直是气象学和机器学习领域的重要研究内容。时间序列预测是其中的一种常见任务,旨在通过分析历史数据来预测未来的天气情况。在本文中,我们将使用线性回归模型来实现天气变化的时间序列预测,并介绍整个预测流程。二......