Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容


Posted in Python onFebruary 23, 2018

1、引言

在Python网络爬虫内容提取器一文我们详细讲解了核心部件:可插拔的内容提取器类gsExtractor。本文记录了确定gsExtractor的技术路线过程中所做的编程实验。这是第二部分,第一部分实验了用xslt方式一次性提取静态网页内容并转换成xml格式。留下了一个问题:javascript管理的动态内容怎样提取?那么本文就回答这个问题。

2、提取动态内容的技术部件

在上一篇python使用xslt提取网页数据中,要提取的内容是直接从网页的source code里拿到的。但是一些Ajax动态内容是在source code找不到的,就要找合适的程序库把异步或动态加载的内容加载上来,交给本项目的提取器进行提取。

python可以使用selenium执行javascript,selenium可以让浏览器自动加载页面,获取需要的数据。selenium自己不带浏览器,可以使用第三方浏览器如Firefox,Chrome等,也可以使用headless浏览器如PhantomJS在后台执行。

3、源代码和实验过程

假如我们要抓取京东手机页面的手机名称和价格(价格在网页源码是找不到的),如下图:

Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容

第一步:利用集搜客谋数台的直观标注功能,可以极快速度自动生成一个调试好的抓取规则,其实是一个标准的xslt程序,如下图,把生成的xslt程序拷贝到下面的程序中即可。注意:本文只是记录实验过程,实际系统中,将采用多种方式把xslt程序注入到内容提取器重。

Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容

第二步:执行如下代码(在windows10, python3.2下测试通过,源代码下载地址请见文章末尾GitHub),请注意:xslt是一个比较长的字符串,如果删除这个字符串,代码没有几行,足以见得Python之强大

#/usr/bin/python 
from urllib import request 
from lxml import etree 
from selenium import webdriver 
import time 
 
# 京东手机商品页面 
url = "http://item.jd.com/1312640.html" 
 
# 下面的xslt是通过集搜客的谋数台图形界面自动生成的 
xslt_root = etree.XML("""\ 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > 
<xsl:template match="/"> 
<商品> 
<xsl:apply-templates select="//*[@id='itemInfo' and count(.//*[@id='summary-price']/div[position()=2]/strong/text())>0 and count(.//*[@id='name']/h1/text())>0]" mode="商品"/> 
</商品> 
</xsl:template> 
 
<xsl:template match="//*[@id='itemInfo' and count(.//*[@id='summary-price']/div[position()=2]/strong/text())>0 and count(.//*[@id='name']/h1/text())>0]" mode="商品"> 
<item> 
<价格> 
<xsl:value-of select="*//*[@id='summary-price']/div[position()=2]/strong/text()"/> 
<xsl:value-of select="*[@id='summary-price']/div[position()=2]/strong/text()"/> 
<xsl:if test="@id='summary-price'"> 
<xsl:value-of select="div[position()=2]/strong/text()"/> 
</xsl:if> 
</价格> 
<名称> 
<xsl:value-of select="*//*[@id='name']/h1/text()"/> 
<xsl:value-of select="*[@id='name']/h1/text()"/> 
<xsl:if test="@id='name'"> 
<xsl:value-of select="h1/text()"/> 
</xsl:if> 
</名称> 
</item> 
</xsl:template> 
</xsl:stylesheet>""") 
 
# 使用webdriver.PhantomJS 
browser = webdriver.PhantomJS(executable_path='C:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe') 
browser.get(url) 
time.sleep(3) 
 
transform = etree.XSLT(xslt_root) 
 
# 执行js得到整个dom 
html = browser.execute_script("return document.documentElement.outerHTML") 
doc = etree.HTML(html) 
# 用xslt从dom中提取需要的字段 
result_tree = transform(doc) 
print(result_tree)

第三步:下图可以看到,网页中的手机名称和价格被正确抓取下来了

Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容

4、接下来阅读

至此,我们通过两篇文章演示怎样抓取静态和动态网页内容,都采用了xslt一次性将需要的内容从网页上提取出来,其实xslt是一个比较复杂的程序语言,如果手工编写xslt,那么还不如写成离散的xpath。如果这个xslt不是手工写出来的,而是程序自动生成的,这就有意义了,程序员再也不要花时间编写和调测抓取规则了,这是很费时费力的工作。下一篇《1分钟快速生成用于网页内容提取的xslt》将讲述怎样生成xslt。

5、集搜客GooSeeker开源代码下载源

1. GooSeeker开源Python网络爬虫GitHub源

6、文档修改历史

2016-05-26:V2.0,增补文字说明
2016-05-29:V2.1,增加第五章:源代码下载源,并更换github源的网址

Python 相关文章推荐
python 参数列表中的self 显式不等于冗余
Dec 01 Python
Python内置函数dir详解
Apr 14 Python
python删除列表中重复记录的方法
Apr 28 Python
Python检测网站链接是否已存在
Apr 07 Python
Python选课系统开发程序
Sep 02 Python
Python实现修改IE注册表功能示例
May 10 Python
python中的变量如何开辟内存
Jun 26 Python
详解flask入门模板引擎
Jul 18 Python
Python异步操作MySQL示例【使用aiomysql】
May 16 Python
Python使用urllib模块对URL网址中的中文编码与解码实例详解
Feb 18 Python
解决更改AUTH_USER_MODEL后出现的问题
May 14 Python
浅谈keras中自定义二分类任务评价指标metrics的方法以及代码
Jun 11 Python
python爬虫获取多页天涯帖子
Feb 23 #Python
Python即时网络爬虫项目启动说明详解
Feb 23 #Python
Python爬豆瓣电影实例
Feb 23 #Python
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
Feb 23 #Python
Python各类图像库的图片读写方式总结(推荐)
Feb 23 #Python
python自动发邮件库yagmail的示例代码
Feb 23 #Python
Python KMeans聚类问题分析
Feb 23 #Python
You might like
PHP脚本的10个技巧(5)
2006/10/09 PHP
js 对象是否存在判断
2009/07/15 Javascript
jquery插件制作 提示框插件实现代码
2012/08/17 Javascript
js获取键盘按键响应事件(兼容各浏览器)
2013/05/16 Javascript
javascript操作excel生成报表示例
2014/05/08 Javascript
浅析javascript中函数声明和函数表达式的区别
2015/02/15 Javascript
javascript中Function类型详解
2015/04/28 Javascript
举例详解AngularJS中ngShow和ngHide的使用方法
2015/06/19 Javascript
javascript中的3种继承实现方法
2016/01/27 Javascript
基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍
2016/05/12 Javascript
jQuery遍历节点树方法分析
2016/09/08 Javascript
AngularJS 单元测试(二)详解
2016/09/21 Javascript
Nodejs中Express 常用中间件 body-parser 实现解析
2017/05/22 NodeJs
jQuery Masonry瀑布流布局神器使用详解
2017/05/25 jQuery
jQuery实现表格冻结顶栏效果
2017/08/20 jQuery
微信小程序返回多级页面的实现方法
2017/10/27 Javascript
echarts学习笔记之图表自适应问题详解
2017/11/22 Javascript
vue select二级联动第二级默认选中第一个option值的实例
2018/01/10 Javascript
使用Angular CLI进行Build(构建)和Serve详解
2018/03/24 Javascript
深入探讨JavaScript的最基本部分之执行上下文
2019/02/12 Javascript
python 字典(dict)遍历的四种方法性能测试报告
2014/06/25 Python
介绍Python中的__future__模块
2015/04/27 Python
Python 制作糗事百科爬虫实例
2016/09/22 Python
在Python中,不用while和for循环遍历列表的实例
2019/02/20 Python
运行tensorflow python程序,限制对GPU和CPU的占用操作
2020/02/06 Python
python递归调用中的坑:打印有值, 返回却None
2020/03/16 Python
matplotlib 画双轴子图无法显示x轴的解决方法
2020/07/27 Python
浅谈Python 钉钉报警必备知识系统讲解
2020/08/17 Python
利用Python发送邮件或发带附件的邮件
2020/11/12 Python
html5 Canvas画图教程(8)—canvas里画曲线之bezierCurveTo方法
2013/01/09 HTML / CSS
HTML5 canvas 瀑布流文字效果的示例代码
2018/01/31 HTML / CSS
override和overload的区别
2016/03/09 面试题
介绍一下linux的文件系统
2015/10/06 面试题
焦点访谈观后感
2015/06/11 职场文书
诚信考试主题班会
2015/08/17 职场文书
Nginx工作模式及代理配置的使用细节
2022/03/21 Servers