1.开始Python中可以进行网页解析的库(图)

优采云 发布时间: 2021-08-17 02:01

  1.开始Python中可以进行网页解析的库(图)

  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库的response对象进行什么操作,这个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 获取有多少个职位

 jobs = r.html.find("h1.call-to-action")

 # xpath 获取

 jobs = r.html.xpath("//h1[@class='call-to-action']")

  方法名很简单,符合Python优雅的风格。下面简单介绍一下这两种方法:

  4. CSS 简单规则5. Xpath 简单规则

  定位元素后,需要获取元素中的内容和属性相关数据,获取文本:

   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)

 

 # for

 

 

 

 

 

 ​

  智能发现和分页是通过迭代器实现的。在这个迭代器中,将使用一个名为 _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 Page 或 Load More 引导。他用这面旗帜来判断。默认情况下,它以列表的形式全局存在:['next','more','older']。我个人认为这种方法非常不灵活,几乎没有可扩展性。有兴趣的可以在github上提交代码优化。

  7.加载js

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

  在 Chromium 中重新加载响应,并用更新的版本替换 HTML 内容,并执行 JavaScript。

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

   r.html.render()

 ​

  第一次使用时,会下载Chromium,但是如果你在中国知道,请自己想办法下载,不要等它自己下载。 render函数可以使用js脚本来操作页面,滚动操作有单独的参数。这对上拉加载等新型页面非常友好。

  8.总结

  Reitz大神设计的东西一如既往的简单好用。我自己做的不多。大部分都是用别人的东西来组装和简化api。这真的是人类。但是,在某些地方,空间仍然得到了优化。希望有兴趣有活力的童鞋可以去github关注这个项目。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线