UDN-企业互联网技术人气社区

板块导航

浏览  : 1043
回复  : 0

[技术讨论] [Python]爬虫技术:(JavaScript渲染)动态页面抓取超级指南

[复制链接]
钻石女王的头像 楼主
发表于 2016-4-4 14:59:10 | 显示全部楼层 |阅读模式
6eLxUXMC.png

  当我们进行网页爬虫时,我们会利用一定的规则从返回的 HTML 数据中提取出有效的信息。但是如果网页中含有 JavaScript 代码,我们必须经过渲染处理才能获得原始数据。此时,如果我们仍采用常规方法从中抓取数据,那么我们将一无所获。浏览器知道如何处理这些代码并将其展现出来,但是我们的程序该如何处理这些代码呢?接下来,我将介绍一个简单粗暴的方法来抓取含有 JavaScript 代码的网页信息。

  大多数人利用lxml和BeautifulSoup这两个包来提取数据。本文中我将不会介绍任何爬虫框架的内容,因为我只利用最基础的lxml包来处理数据。也许你们会好奇为啥我更喜欢lxml。那是因为lxml利用元素遍历法来处理数据而不是像BeautifulSoup一样利用正则表达式来提取数据。本文中我将介绍一个非常有趣的案例——之前我突然发现我的文章出现在最近的 Pycoders weekly issue 147中,因此我想爬取 Pycoders weekly 中所有档案的链接。

P68lpeHS.png

  很明显,这是一个含有 JavaScript 渲染的网页。我想要抓取网页中所有的档案信息和相应的链接信息。那么我该怎么处理呢?首先,我们利用 HTTP 方法无法获得任何信息。
  1. import requests
  2. from lxml import html

  3. # storing response
  4. response = requests.get('http://pycoders.com/archive')
  5. # creating lxml tree from response body
  6. tree = html.fromstring(response.text)

  7. # Finding all anchor tags in response
  8. print tree.xpath('//div[@class="campaign"]/a/@href')
复制代码

  当我们运行上述代码时,我们无法获得任何信息。这怎么可能呢?网页中明明显示那么多档案的信息。接下来我们需要考虑如何解决这个问题?

  如何获取内容信息?

  接下来我将介绍如何利用 Web kit 从 JS 渲染网页中获取数据。什么是 Web kit呢?Web kit 可以实现浏览器所能处理的任何事情。对于某些浏览器来说,Web kit就是其底层的网页渲染工具。Web kit 是QT库的一部分,因此如果你已经安装QT和PyQT4库,那么你可以直接运行之。

  你可以利用命令行来安装该软件库:
  1. sudo apt-get install python-qt4
复制代码

  现在所有的准备工作已经完成,接下来我们将使用一个全新的方法来提取信息。

  解决方案

  我们首先通过 Web kit 发送请求信息,然后等待网页被完全加载后将其赋值到某个变量中。接下来我们利用lxml从 HTML 数据中提取出有效的信息。这个过程需要一点时间,不过你会惊奇地发现整个网页被完整地加载下来了。
  1. import sys
  2. from PyQt4.QtGui import *
  3. from PyQt4.Qtcore import *
  4. from PyQt4.QtWebKit import *

  5. class Render(QWebPage):
  6.     def __init__(self, url):
  7.         self.app = QApplication(sys.argv)
  8.         QWebPage.__init__(self)
  9.         self.loadFinished.connect(self._loadFinished)
  10.         self.mainFrame().load(QUrl(url))
  11.         self.app.exec_()

  12.     def _loadFinished(self, result):
  13.         self.frame = self.mainFrame()
  14.         self.app.quit()
复制代码
  1.   类Render可以用来渲染网页,当我们新建一个Render类时,它可以将url中的所有信息加载下来并存到一个新的框架中。
  2. url = 'http://pycoders.com/archive/'
  3. # This does the magic.Loads everything
  4. r = Render(url)
  5. # Result is a QString.
  6. result = r.frame.toHtml()
复制代码

  利用以上的代码我们将 HTML 结果储存到变量result中,由于lxml无法直接处理该特殊的字符串数据,因此我们需要转换数据格式。
  1. # QString should be converted to string before processed by lxml
  2. formatted_result = str(result.toAscii())

  3. # Next build lxml tree from formatted_result
  4. tree = html.fromstring(formatted_result)

  5. # Now using correct Xpath we are fetching URL of archives
  6. archive_links = tree.xpath('//div[@class="campaign"]/a/@href')
  7. print archive_links
复制代码

  利用上述代码我们可以获得所有的档案链接信息,接下来我们可以利用这些 Render和这些URL链接来提取文本内容信息。Web kit 提供了一个强大的网页渲染工具,我们可以利用这个工具从 JS 渲染的网页中抓取出有效的信息。

hZGHYbP0.png

  本文中我介绍了一个如何从 JS 渲染的网页中抓取信息的有效方法,这个工具虽然速度比较慢,但是却非常简单粗暴。我希望你会喜欢这篇文章。现在你可以将该方法运用到任何你觉得难以处理的网页中。

  祝一切顺利。

原文链接:https://impythonist.wordpress.co ... rendered-web-pages/
原文作者:Naren Aryan
译者:fibears
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部