Python网页解析库:用requests-html爬取网页

1. 开始

Python 中可以进行网页解析的库有很多,常见的有 BeautifulSoup 和 lxml 等。在网上玩爬虫的文章通常都是介绍 BeautifulSoup 这个库,我平常也是常用这个库,最近用 Xpath 用得比较多,使用 BeautifulSoup 就不大习惯,很久之前就知道 Reitz 大神出了一个叫 Requests-HTML 的库,一直没有兴趣看,这回可算歹着机会用一下了。

使用 pip install requests-html安装,上手和 Reitz 的其他库一样,轻松简单:

from requests_html import HTMLSession
session = HTMLSession() r = session.get('https://www.python.org/jobs/')

这个库是在 requests 库上实现的,r 得到的结果是 Response 对象下面的一个子类,多个一个 html 的属性。所以 requests 库的响应对象可以进行什么操作,这个 r 也都可以。如果需要解析网页,直接获取响应对象的 html 属性:

r.html

2. 原理

不得不膜拜 Reitz 大神太会组装技术了。实际上 HTMLSession 是继承自 requests.Session 这个核心类,然后将 requests.Session 类里的 requests 方法改写,返回自己的一个 HTMLResponse 对象,这个类又是继承自 requests.Response,只是多加了一个 _from_response 的方法来构造实例:

class HTMLSession(requests.Session):
# 重写 request 方法,返回 HTMLResponse 构造
def request(self, *args, **kwargs) -> HTMLResponse:
r = super(HTMLSession, self).request(*args, **kwargs)
return HTMLResponse._from_response(r, self)
class HTMLResponse(requests.Response):
# 构造器
@classmethod
def _from_response(cls, response, session: Union['HTMLSession', 'AsyncHTMLSession']):
html_r = cls(session=session)
html_r.__dict__.update(response.__dict__)
return html_r

之后在 HTMLResponse 里定义属性方法 html,就可以通过 html 属性访问了,实现也就是组装 PyQuery 来干。核心的解析类也大多是使用 PyQuery 和 lxml 来做解析,简化了名称,挺讨巧的。

3. 元素定位

元素定位可以选择两种方式:

css 选择器

  • css选择器
  • xpath
# css 获取有多少个职位
jobs = r.html.find("h1.call-to-action")
# xpath 获取
jobs = r.html.xpath("//h1[@class='call-to-action']")

方法名非常简单,符合 Python 优雅的风格,这里不妨对这两种方式简单的说明:

4. CSS 简单规则

  • 标签名 h1
  • id 使用 #id 表示
  • class 使用 .class_name 表示
  • 谓语表示:h1[prop=value]

5. Xpath简单规则

  • 路径 // 或者 /
  • 标签名
  • 谓语 [@prop=value]
  • 轴定位 名称::元素名[谓语]

定位到元素以后势必要获取元素里面的内容和属性相关数据,获取文本:

jobs.text
jobs.full_text

获取元素的属性:

attrs = jobs.attrs
value = attrs.get("key")

还可以通过模式来匹配对应的内容:

## 找某些内容匹配
r.html.search("Python {}")
r.html.search_all()

这个功能看起来比较鸡肋,可以深入研究优化一下,说不定能在 github 上混个提交。

6. 人性化操作

除了一些基础操作,这个库还提供了一些人性化的操作。比如一键获取网页的所有超链接,这对于整站爬虫应该是个福音,URL 管理比较方便:

r.html.absolute_links
r.html.links

内容页面通常都是分页的,一次抓取不了太多,这个库可以获取分页信息:

print(r.html)
# 比较一下
for url in r.html:
print(url)

结果如下:

# print(r.html)
<HTML url='https://www.python.org/jobs/'>
# for
<HTML url='https://www.python.org/jobs/'>
<HTML url='https://www.python.org/jobs/?page=2'>
<HTML url='https://www.python.org/jobs/?page=3'>
<HTML url='https://www.python.org/jobs/?page=4'>
<HTML url='https://www.python.org/jobs/?page=5'>

通过迭代器实现了智能发现分页,这个迭代器里面会用一个叫 _next 的方法,贴一段源码感受下:

def get_next():
candidates = self.find('a', containing=next_symbol) for candidate in candidates:
if candidate.attrs.get('href'):
# Support 'next' rel (e.g. reddit).
if 'next' in candidate.attrs.get('rel', []):
return candidate.attrs['href']

通过查找 a 标签里面是否含有指定的文本来判断是不是有下一页,通常我们的下一页都会通过 下一页 或者 加载更多 来引导,他就是利用这个标志来进行判断。默认的以列表形式存在全局:['next', 'more', 'older']。我个人认为这种方式非常不灵活,几乎没有扩展性。感兴趣的可以往 github 上提交代码优化。

7. 加载 js

也许是考虑到了现在 js 的一些异步加载,这个库支持 js 运行时,官方说明如下:

Reloads the response in Chromium, and replaces HTML content

with an updated version, with JavaScript executed.

使用非常简单,直接调用以下方法:

r.html.render()

第一次使用的时候会下载 Chromium,不过国内你懂的,自己想办法去下吧,就不要等它自己下载了。render 函数可以使用 js 脚本来操作页面,滚动操作单独做了参数。这对于上拉加载等新式页面是非常友好的。

8. 总结

Reitz 大神设计出来的东西还是一如既往的简单好用,自己不多做,大多用别人的东西组装,简化 api。真是够人性。不过有的地方还是优化空间,希望有兴趣和精力的童鞋去 github 上关注一下这个项目。

Python网页解析库:用requests-html爬取网页的更多相关文章

  1. PYTHON 爬虫笔记八:利用Requests+正则表达式爬取猫眼电影top100(实战项目一)

    利用Requests+正则表达式爬取猫眼电影top100 目标站点分析 流程框架 爬虫实战 使用requests库获取top100首页: import requests def get_one_pag ...

  2. 简单又强大的pandas爬虫 利用pandas库的read_html()方法爬取网页表格型数据

    文章目录 一.简介 二.原理 三.爬取实战 实例1 实例2 一.简介 一般的爬虫套路无非是发送请求.获取响应.解析网页.提取数据.保存数据等步骤.构造请求主要用到requests库,定位提取数据用的比 ...

  3. python网络爬虫之scrapy 调试以及爬取网页

    Shell调试: 进入项目所在目录,scrapy shell “网址” 如下例中的: scrapy shell http://www.w3school.com.cn/xml/xml_syntax.as ...

  4. python 爬虫(一) requests+BeautifulSoup 爬取简单网页代码示例

    以前搞偷偷摸摸的事,不对,是搞爬虫都是用urllib,不过真的是很麻烦,下面就使用requests + BeautifulSoup 爬爬简单的网页. 详细介绍都在代码中注释了,大家可以参阅. # -* ...

  5. [python] 常用正则表达式爬取网页信息及分析HTML标签总结【转】

    [python] 常用正则表达式爬取网页信息及分析HTML标签总结 转http://blog.csdn.net/Eastmount/article/details/51082253 标签: pytho ...

  6. 常用正则表达式爬取网页信息及HTML分析总结

    Python爬取网页信息时,经常使用的正则表达式及方法. 1.获取<tr></tr>标签之间内容 2.获取<a href..></a>超链接之间内容 3 ...

  7. urllib基础-利用网站结构爬取网页-百度搜索

    有的时候爬取网页,可以利用网站额结构特点爬取网页 在百度搜索框中输入搜索内容,单击搜索,浏览器会发送一个带有参数的url请求.尝试删除其中的一些参数,只剩下wd这个参数.发现wd是搜索内容.这样程序可 ...

  8. Python使用urllib,urllib3,requests库+beautifulsoup爬取网页

    Python使用urllib/urllib3/requests库+beautifulsoup爬取网页 urllib urllib3 requests 笔者在爬取时遇到的问题 1.结果不全 2.'抓取失 ...

  9. python requests库爬取网页小实例:爬取网页图片

    爬取网页图片: #网络图片爬取 import requests import os root="C://Users//Lenovo//Desktop//" #以原文件名作为保存的文 ...

随机推荐

  1. 如何在同一Linux服务器上创建多站点

    在没有域名的情况下,怎样才能创建出多站点访问?这个问题困扰我许久,之后阅读了<http权威指南>,这本让我恍然大悟.这里说明了从浏览器如何解析域名,再请求服务器,服务器收到请求后是如何处理 ...

  2. 踩到一个关于分布式锁的非比寻常的BUG!

    你好呀,我是歪歪. 提到分布式锁,大家一般都会想到 Redis. 想到 Redis,一部分同学会说到 Redisson. 那么说到 Redisson,就不得不掰扯掰扯一下它的"看门狗&quo ...

  3. JuiceFS v1.0 beta3 发布,支持 etcd、Amazon MemoryDB、Redis Cluster

    JuiceFS v1.0 beta3 在元数据引擎方面继续增强,新增 etcd 支持小于 200 万文件的使用场景,相比 Redis 可以提供更好的可用性和安全性.同时支持了 Amazon Memor ...

  4. 解读论文《Agglomerative clustering of a search engine query log》,以解决搜索推荐相关问题

    <Agglomerative clustering of a search engine query log> 论文作者:Doug Beeferman 本文将解读此篇论文,此论文利用搜索日 ...

  5. falcon-eye-本机系统监控WebUI

    falcon-eye是一个简单的单机版基于WebUI的Linux系统监控工具. 安装falcon-eye root@localhost:~# mkdir falcon-eye root@localho ...

  6. CF1682C. LIS or Reverse LIS?

    题意:给\(n\)个数,问你能构出严格上升子序列长度和下降子序列长度最小值的最大值. 思路: 如果一个数出现至少两次,ans++. 统计出现一次的个数,因为再最长上升子序列中,只能有一个值能贡献到下降 ...

  7. Eoapi — 一个可拓展的开源 API 工具

    ​ 在社区中时常会出现"抱怨某商业产品越来越臃肿"的声音,API 工具也是如此.从最早期只做 API 调试的工具,到经过多年的演进后集成全面功能的"庞然大物", ...

  8. Typecho博客转移服务器,数据备份.

    目录 Typecho博客转移服务器,数据备份. 简述操作(有基础的mjj看这个简述就可以了.) 详细步骤(建议小白来看, 已经在很多详细方面进行说明了.) 备份篇 备份导入与数据库转移篇 重新部署ty ...

  9. .NET中按预定顺序执行任务

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月1日. 一.说明 在.NET中线程可以定义按先后顺序进行执行,适合部分有先后次序的业务逻辑.Task也可以按照预定义的先后顺序执行 ...

  10. Windows家庭版-添加Hyper-V

    新建一个hyper-v.cmd文件,内容为 pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum & ...