上一篇文章爬取动态网页python+selenium+webdriver介绍了爬取动态网站的一种模拟浏览器的方法,该方法的优劣也很明显
优:
可以模拟任何人的操作,输入账号密码,点击登录等等操作
劣:
1.每次执行都要打开桌面上的Chrome浏览器(自动化测试需要)
2.浏览器的各个操作步骤都需要sleep几秒进行等待,效率低
本文针对两个劣点的进行解决
PhantomJS
webdriver有很多种类的浏览器比如Internet Explorer、Chrome和 Firefox等,PhantomJS是一个无界面的浏览器,可以解决第一个问题。
渲染的问题
一个含有 JS 渲染的网页。想要抓取网页中所有信息。如果我们利用 HTTP 方法无法获得任何信息。
import requests
from lxml import html
# storing response
response = requests.get('http://pycoders.com/archive')
# creating lxml tree from response body
tree = html.fromstring(response.text)
# Finding all anchor tags in response
print tree.xpath('//div[@class="campaign"]/a/@href')
因为这是动态渲染的网站,我们只能拿到一堆还没被解析为html的js代码。
Web kit
什么是 Web kit呢?
Web kit 可以实现浏览器所能处理的任何事情。对于某些浏览器来说,Web kit就是其底层的网页渲染工具。
Web kit 是 QT 库的一部分,因此需要安装 QT 和PyQT4 库来使用Web kit
sudo apt-get install python-qt4
注意:
上篇文章中使用selenium+webdriver其实也是通过浏览器来进行渲染那些js,原理相同
解析数据
思路:我们首先通过 Web kit 发送请求信息,然后等待网页被完全加载后将其赋值到某个变量中。接下来我们利用 lxml 从 HTML 数据中提取出有效的信息。
1.类 Render 可以用来渲染网页,当我们新建一个 Render 类时,它可以将 url 中的所有信息加载下来并存到一个新的框架中。
import sys
from PyQt4.QtGui import *
from PyQt4.Qtcore import *
from PyQt4.QtWebKit import *
class Render(QWebPage):
def __init__(self, url):
self.app = QApplication(sys.argv)
QWebPage.__init__(self)
self.loadFinished.connect(self._loadFinished)
self.mainFrame().load(QUrl(url))
self.app.exec_()
def _loadFinished(self, result):
self.frame = self.mainFrame()
self.app.quit()
2.利用以上的代码我们将 HTML 结果储存到变量 result 中
url = 'http://pycoders.com/archive/'
# This does the magic.Loads everything
r = Render(url)
# Result is a QString.
result = r.frame.toHtml()
3.转换数据格式并解析
# QString should be converted to string before processed by lxml
formatted_result = str(result.toAscii())
# Next build lxml tree from formatted_result
tree = html.fromstring(formatted_result)
# Now using correct Xpath we are fetching URL of archives
archive_links = tree.xpath('//div[@class="campaign"]/a/@href')
print archive_links
总结
1.动态网站爬取核心步骤是渲染js
2.python+selenium+webdriver方式是模拟出真实环境解决的,既可以解决渲染,又可以附带很多人的操作(输入、点击、最大化等),功能强大但是纯采集的话效率略低
3.python+Web kit方式直接把渲染的核心部件拿出来进行解决,这种方式简单直接,作为纯采集来说是首选,但是受限于需要登录验证的网站