顶点小说

装xpath helper

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

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

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

爬虫介绍

分类:

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

介绍:

程序发起请求(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]

《从零开始学习Python爬虫:顶点小说全网爬取实战》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. C语言:约瑟夫问题——使用循环链表解决

    传说有30个乘客同乘一条船,因为严重超载,加上风浪水作,危险万分.船长告诉乘客,只有将全船一半的乘客投入海 中,其余人才能幸免于难.他们约定了一个规则:30个人围成一圈,由第一个人数起,依次报数,数到 ...

  2. 阿里云sdk调用

    slb调用 环境包安装 pip install alibabacloud_credentials  --trusted-host mirrors.aliyun.com  -i  http://mirr ...

  3. windows下使用winget快速安装nvm

    前置条件: 操作系统 >= win10 安装 首先使用winget搜索nvm包 winget search nvm #搜索结果如下图 安装nvm winget install CoreyButl ...

  4. EasyUI框架Datagrid(数据表格)的实现,以及Datagrid的分页显示(详解)

    在前端页面中使用EasyUI框架时,通常会使用EasyUI自带的datagrid(数据表格)样式,下面我们对datagrid样式进行简单的介绍,并且会对datagrid的分页显示进行详细的介绍. Ea ...

  5. WPF多显示器问题 - WindowState

    标签 wpf multiple-monitors 一段时间以来,我一直试图让我的 WPF 应用程序跨越多个监视器,并且几乎可以正常工作.当我设置以下行时,问题似乎出现了: win1.WindowSta ...

  6. 调试YOLOv3/YOLOv5过程中遇到的问题汇总

    今日立冬 yolov1 yolo1论文 https://www.bilibili.com/video/BV15w411Z7LG yolo2论文 https://www.bilibili.com/vid ...

  7. 为什么魂斗罗只有128KB却能实现那么长的剧情有答案了

    PPU 首发公号:Rand_cs 本文继续讲述 NES 的基本原理,承接上文的 CPU,本文来讲述 PPU,较为复杂,慢慢来看.例子基本都是使用的魂斗罗,看完本文相信对那问题"为什么魂斗罗只 ...

  8. 大量索引场景下 Easysearch 和 Elasticsearch 的吞吐量差异

    最近有客户在使用 Elasticsearch 搜索服务时发现集群有掉节点,并且有 master 收集节点信息超时的日志,节点的负载也很高,不只是 data 节点,master 和协调节点的 cpu 使 ...

  9. web框架及Django简介

    WEB框架 Web框架是一种开发框架,用来支持动态网站.网络应用和网络服务的开发.这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方法. web框架已经实现了很多功能 ...

  10. Vue学习:13.生命周期综合

    0基础如何进入IT行业? 简介:对于没有任何相关背景知识的人来说,如何才能成功进入IT行业?是否有一些特定的方法或技巧可以帮助他们实现这一目标? 方向一:学习路径 明确兴趣和目标:首先确定你对IT领域 ...