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 合并文件的具体实例
Aug 08 Python
仅用500行Python代码实现一个英文解析器的教程
Apr 02 Python
Python iter()函数用法实例分析
Mar 17 Python
pandas 将list切分后存入DataFrame中的实例
Jul 03 Python
对python numpy.array插入一行或一列的方法详解
Jan 29 Python
python接口自动化(十六)--参数关联接口后传(详解)
Apr 16 Python
python networkx 根据图的权重画图实现
Jul 10 Python
Python中list循环遍历删除数据的正确方法
Sep 02 Python
python破解bilibili滑动验证码登录功能
Sep 11 Python
pycharm运行程序时看不到任何结果显示的解决
Feb 21 Python
Python fileinput模块如何逐行读取多个文件
Oct 05 Python
Python OpenCV 彩色与灰度图像的转换实现
Jun 05 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中filter函数验证、过滤用户输入的数据
2014/01/13 PHP
YII中Ueditor富文本编辑器文件和图片上传的配置图文教程
2017/03/15 PHP
Javascript Global对象
2009/08/13 Javascript
jQuery select表单提交省市区城市三级联动核心代码
2014/06/09 Javascript
使用documentElement正确取得当前可见区域的大小
2014/07/25 Javascript
js常用系统函数用法实例分析
2015/01/12 Javascript
jQuery插件实现大图全屏图片相册
2015/03/14 Javascript
JavaScript中连接操作Oracle数据库实例
2015/04/02 Javascript
原生js和jQuery写的网页选项卡特效对比
2015/04/27 Javascript
javascript中闭包(Closure)详解
2016/01/06 Javascript
详解JavaScript中的事件流和事件处理程序
2016/05/20 Javascript
vue.js指令v-model实现方法
2016/12/05 Javascript
详解vue.js全局组件和局部组件
2017/04/10 Javascript
解决vue+element 键盘回车事件导致页面刷新的问题
2018/08/25 Javascript
vue实现分页组件
2020/06/16 Javascript
vue中destroyed方法的使用说明
2020/07/21 Javascript
vue 路由meta 设置导航隐藏与显示功能的示例代码
2020/09/04 Javascript
[03:14]DOTA2斧王 英雄基础教程
2013/11/26 DOTA
python基于隐马尔可夫模型实现中文拼音输入
2016/04/01 Python
python 实现自动远程登陆scp文件实例代码
2017/03/13 Python
Python实现京东秒杀功能代码
2019/05/16 Python
Python网络爬虫四大选择器用法原理总结
2020/06/01 Python
css3的过滤效果简单实例
2016/08/03 HTML / CSS
canvas绘制太极图的实现示例
2020/04/29 HTML / CSS
天美时手表加拿大官网:Timex加拿大
2016/09/01 全球购物
西班牙著名的珠宝首饰品牌:P D PAOLA
2018/09/15 全球购物
周仰杰(JIMMY CHOO)英国官方网站:闻名世界的鞋子品牌
2018/10/28 全球购物
当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
2014/09/09 面试题
*p++ 自增p 还是p所指向的变量
2016/07/16 面试题
如何利用find命令查找文件
2015/02/07 面试题
服装电子商务创业计划书
2014/01/30 职场文书
公司请假条范文
2014/04/11 职场文书
生产现场禁烟通知
2015/04/23 职场文书
项目投资意向书范本
2015/05/09 职场文书
2015年乡镇纪委工作总结
2015/05/26 职场文书
JavaScript严格模式不支持八进制的问题讲解
2021/11/07 Javascript