本文讲解怎样用Python驱动Firefox浏览器写一个简易的网页数据采集器。开源Python即时网络爬虫项目将与Scrapy(基于twisted的异步网络框架)集成,所以本例将使用Scrapy采集淘宝这种含有大量ajax代码的网页数据,但是要注意本例一个严重缺陷:用Selenium加载网页的过程发生在Spider中,破坏了Scrapy的架构原则。所以,本例只是为了测试Firefox驱动和ajax网页数据采集这两个技术点,用于正式运行环境中必须予以修改,后续的文章将专门讲解修正后的实现。
请注意,本例用到的xslt文件是通过MS谋数台保存提取器后,通过API接口获得,一方面让python代码变得简洁,另一方面,节省调试采集规则的时间。详细操作请查看 Python即时网络爬虫:API说明
2.1,环境准备
需要执行以下步骤,准备Python开发和运行环境:
上述步骤展示了两种安装:1,安装下载到本地的wheel包;2,用Python安装管理器执行远程下载和安装。
2.2,开发和测试过程
以下代码默认都是在命令行界面执行
1),创建scrapy爬虫项目simpleSpider
E:/python-3.5.1>scrapystartprojectsimpleSpider
2),修改settings.py配置
有些网站会在根目录下放置一个名字为robots.txt的文件,里面声明了此网站希望爬虫遵守的规范,Scrapy默认遵守这个文件制定的规范,即ROBOTSTXT_OBEY默认值为True。在这里需要修改ROBOTSTXT_OBEY的值,找到E:python-3.5.1simpleSpidersimpleSpider下文件settings.py,更改ROBOTSTXT_OBEY的值为False。
3),导入API模块
在项目目录E:python-3.5.1simpleSpider下创建文件gooseeker.py(也可以在开源Python即时网络爬虫GitHub源 的core文件夹中直接下载),代码如下:
#!/usr/bin/python # -*- coding: utf-8 -*- # 模块名: gooseeker # 类名: GsExtractor # Version: 2.0 # 说明: html内容提取器 # 功能: 使用xslt作为模板,快速提取HTML DOM中的内容。 # released by 集搜客(http://www.gooseeker.com) on May 18, 2016 # github: https://github.com/FullerHua/jisou/core/gooseeker.py from urllib import request from urllib.parseimport quote from lxmlimport etree import time class GsExtractor(object): def _init_(self): self.xslt = "" # 从文件读取xslt def setXsltFromFile(self , xsltFilePath): file = open(xsltFilePath , 'r' , encoding='UTF-8') try: self.xslt = file.read() finally: file.close() # 从字符串获得xslt def setXsltFromMem(self , xsltStr): self.xslt = xsltStr # 通过GooSeeker API接口获得xslt def setXsltFromAPI(self , APIKey , theme, middle=None, bname=None): apiurl = "http://www.gooseeker.com/api/getextractor?key="+ APIKey +"&theme="+quote(theme) if (middle): apiurl = apiurl + "&middle="+quote(middle) if (bname): apiurl = apiurl + "&bname="+quote(bname) apiconn = request.urlopen(apiurl) self.xslt = apiconn.read() # 返回当前xslt def getXslt(self): return self.xslt # 提取方法,入参是一个HTML DOM对象,返回是提取结果 def extract(self , html): xslt_root = etree.XML(self.xslt) transform = etree.XSLT(xslt_root) result_tree = transform(html) return result_tree
4),创建SimpleSpider爬虫类
在项目目录E:python-3.5.1simpleSpidersimpleSpiderspiders下创建文件simplespider.py,代码如下:
# -*- coding: utf-8 -*- import time import scrapy from lxmlimport etree from seleniumimport webdriver from gooseekerimport GsExtractor class SimpleSpider(scrapy.Spider): name = "simplespider" allowed_domains = ["taobao.com"] start_urls = [ "https://item.taobao.com/item.htm?spm=a230r.1.14.197.e2vSMY&id=44543058134&ns=1&abbucket=10" ] def __init__(self): # use any browser you wish self.browser = webdriver.Firefox() def getTime(self): # 获得当前时间戳 current_time = str(time.time()) m = current_time.find('.') current_time = current_time[0:m] return current_time def parse(self, response): print("start...") #start browser self.browser.get(response.url) #loading time interval time.sleep(3) #get xslt extra = GsExtractor() extra.setXsltFromAPI("API KEY" , "淘宝天猫_商品详情30474") # get doc html = self.browser.execute_script("return document.documentElement.outerHTML"); doc = etree.HTML(html) result = extra.extract(doc) # out file file_name = 'F:/temp/淘宝天猫_商品详情30474_' + self.getTime() + '.xml' open(file_name,"wb").write(result) self.browser.close() print("end")
5),启动爬虫
在E:python-3.5.1simpleSpider项目目录下执行命令
E:/python-3.5.1/simpleSpider>scrapycrawlsimplespider
6),输出文件
采集到的网页数据结果文件是:淘宝天猫_商品详情30474_1466064544.xml
调用Firefox,IE等全特性浏览器显得有点太重量级,很多场合可以考虑轻量级的浏览器内核,比如,casperjs和phantomjs等。同时运行在没有界面的浏览器(headless browser,无头浏览器)模式下,也许可以对网页数据采集性能有所提升。
然后,最重要的一点是要写一个 Scrapy 的下载器,专门驱动这些浏览器采集网页数据,也就是把这个功能从Spider中迁移出来,这样才符合Scrapy的整体框架原则,实现事件驱动的工作模式。
1, Python即时网络爬虫:API说明
2, API例子:用Java/JavaScript下载内容提取器
1, 开源Python即时网络爬虫GitHub源
1,2016-06-28:V1.02,2016-06-28:V1.1,在第一段明显位置注明本案例的缺陷