爬取千千小说 -- xpath
今天以其中一本小说为例,讲一下下载小说的主体部分,了解正常的爬取步骤,用到的是request和xpath。
一、访问千千小说网址: https://www.qqxsnew.com/
二、随便选一部小说,打开章节目录界面(比方说魔道祖师):https://www.qqxsnew.com/18/18991/
三、开始编写代码。
a. 利用request访问网页,是get请求还是post请求要看网页上面写的是啥
右击检查,选择network,随便找个页面,看下request Method方法是什么。
url = "https://www.qqxsnew.com/18/18991/" html = requests.get(url, headers=headers).text
b. 得到网页的html页面(html页面 == 在网页鼠标右击“查看网页源代码”),获取章节名字和章节链接。
章节名字和章节链接获取需要用到XPath --》在网页鼠标右击检查 --》定位到任意章节(如第一章)--》copy --》copy XPath --》 //*[@id="list"]/dl/dd[13]/a
如果安装过XPath插件的话,可以将上面复制的XPath在插件里面查询,可以看到只查询到了一个
我们的目的是获取到所有章节的名字和链接,分析上面XPath的字串,反显dd[13]这个地方是定位,每个dd都是一个章节,所以我们模糊定位看看
咦,可以看出来dd里面的内容都出来了,但是前面12章的内容不是我们需要的,我们要的是从第一章开始,所以需要把它们过滤掉,position是一个定位的函数,大于12是说从第13位开始,也就是第一章
这数据正好是我们想要提取的文字,所以我们已经得到了文字提取的XPath字串://*[@id="list"]/dl/dd[position()>12]/a
文字和链接都在a标签里面,链接在href属性里面,所以链接的XPath字串://*[@id="list"]/dl/dd[position()>12]/a/@href
好了,前面是在分析XPath字串是怎么得到的,如果自己对XPath语法熟的话,也可以自己写提取字串,然后用插件去验证,或者直接用代码验证都是可以的。现在我们把它放到代码中去
# 获取a标签对象 chapter_titles_obj = datas.xpath('//*[@id="list"]/dl/dd[position()>12]/a') for chapter_title_obj in chapter_titles_obj: # 获取a标签文本 chapter_title_text = chapter_title_obj.xpath('./text()')[0] # 获取a标签的链接 chapter_url = chapter_title_obj.xpath('./@href')[0]
打印出来看看结果
c. 每个章节的链接都拿到了,接下来就是请求了,这个不多说,和上面请求的方法一样,XPath获取方法也相同。
d. 存储获取到的数据
for content_chapter_text in content_chapter: print(content_chapter_text) with open("魔道祖师/" + chapter_title_text + ".txt", 'a', encoding='utf-8') as f: f.write(content_chapter_text)
这样,一篇小说从访问到下载的过程就结束了。
完整代码
#!/usr/bin/env python # _*_ coding: UTF-8 _*_ """================================================= @Project -> File : six-dialog_design -> qianqian.py @IDE : PyCharm @Author : zihan @Date : 2020/5/25 14:50 @Desc : =================================================""" import requests from lxml import etree headers = { 'User-Agent': "" } def main(): url = "https://www.qqxsnew.com/18/18991/" html = requests.get(url, headers=headers).text datas = etree.HTML(html) chapter_titles_obj = datas.xpath('//*[@id="list"]/dl/dd[position()>12]/a') for chapter_title_obj in chapter_titles_obj: chapter_title_text = chapter_title_obj.xpath('./text()')[0] chapter_url = chapter_title_obj.xpath('./@href')[0] chapter_url = "https://www.qqxsnew.com" + chapter_url # 对每一章的链接发送请求 html_chapter = requests.get(chapter_url, headers=headers).text datas_chapter = etree.HTML(html_chapter) content_chapter = datas_chapter.xpath('//*[@id="content"]/text()') print(chapter_title_text, "开始下载") for content_chapter_text in content_chapter: print(content_chapter_text) with open("魔道祖师/" + chapter_title_text + ".txt", 'a', encoding='utf-8') as f: f.write(content_chapter_text) if __name__ == '__main__': main()
OK。如果想要批量下载,或者选择下载等,只是改变url而已,了解主体方法后,这些都不难。
原文地址:https://www.cnblogs.com/smart-zihan/p/12963389.html
- 总结了一些指针易出错的常见问题(一)
- Eureka 服务上下线监控
- 程序员面试50题(1)—查找最小的k个元素[算法]
- Netty4自带编解码器详解
- C和指针小结(C/C++程序设计)
- Netty-整合Protobuf高性能数据传输
- Netty-整合kryo高性能数据传输
- 40个重要的HTML 5面试问题及答案
- js调用原生API--陀螺仪和加速器
- OpenDaylight开发-DataStoreChange监听器三种类型
- express模拟接口
- spring boot开发的日志系统
- elasticsearch 5.0.1安装analysis-ik分词器
- Spring Cloud中Feign如何统一设置验证token
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 搭建简易的物联网服务端和客户端-邮件通知(十九)
- LeetCode37|两颗二叉搜索树中所有元素
- LeetCode45|数组中重复的数据
- 搭建简易的物联网服务端和客户端-网络控制(二十)
- LeetCode44|在每个树行中找最大值
- LeetCode43|最大层内元素和
- 搭建简易的物联网服务端和客户端-Maibu控制(二十一)
- LeetCode42|层数最深叶子节点的和
- LeetCode41|数组中数组出现的次数
- Django后台管理界面修改(源文件修改)
- 前端工程师不可不知的Nginx知识
- Django1.11 简单登录注册
- 基因表达聚类分析之初探SOM - 自组织特征图
- JMH - Java 代码性能测试的终极利器、必须掌握
- 从零搭建Spring Boot脚手架(6):整合Redis作为缓存