Scrapy+Selenium+PhantomJS+MongoDB实现获取动态数据
2017-04-01 00:00
477 查看
摘要: PhantomJS实现Scrapy抓取动态数据
项目源码下载:码云--推荐,Github
思路:用PhantomJS来模仿用户的动作(如点击、下拉等)来实现完全获取网页的数据以及元素。
缺点:受限于网络状况,PhantomJS拉取数据时很慢;效率不高、占用内存大,个人电脑无法实现大量爬取。
用Pycharm打开该项目,项目结构如下:
首先需要下载PhantomJS驱动,需要在系统环境变量中设置PhantomJS的路径,否则运行时会找不到PhantomJS。或者在初始化时也可以手动指定PhantomJS的路径。
应对懒加载:有些网站需要进行滚动条滚动来加载其余数据,针对此,我们将窗口尽量设置大一点,再用PhantomJS进行滚动。
如果需要进行网页点击等操作,可以加上等待事件,等待某个元素加载完毕之后再将PhantomJS得到的数据返回给爬虫处理。举个简单的例子:
先设定一个等待事件,等待时间为15ms,然后通过xpath找到这个按钮并进行点击,然后可以等待某个元素加载,加载成功即继续,不成功可以进行其他处理。
至此我们的中间件PhantomJS就算设置完了,还需要在Scrapy的配置中启用就可以了,非常方便。
连接MongoDB所需要的所有配置都存在settings里面,这里将其调用出来直接使用就好了。
通过配置pipelines,可以将爬取到的item全部存入MongoDB中。
需要设置HTTP headers中的user-agent,让爬虫看起来更像是一个浏览器的请求。
可以在这里配置MongoDB需要使用的地址、数据库名、用户等,当然也可以用其他方法来减少噪音的hardcode
启用刚刚定义的DemoPipelines
禁用Scrapy内置中间件,启用我们自己定义的中间件。
禁用robot.txt,某些网站会根据robot.txt来指定搜索引擎蜘蛛只抓取指定的内容,或者是禁止搜索引擎蜘蛛抓取网站的部分或全部内容。
到这里就结束啦,本人也是个小菜鸟,在不断学习中,欢迎指教。
项目源码下载:码云--推荐,Github
背景介绍
问题:由于有些网站的数据由动态获取(Ajax、JSP)而来,而一般爬虫只能爬取静态数据。爬取到数据后存入MongoDB。思路:用PhantomJS来模仿用户的动作(如点击、下拉等)来实现完全获取网页的数据以及元素。
缺点:受限于网络状况,PhantomJS拉取数据时很慢;效率不高、占用内存大,个人电脑无法实现大量爬取。
开始实施
用命令行启动一个Scrapy项目
MacBook-Pro:project_scrapy lewisgong$ scrapy startproject demo New Scrapy project 'demo', using template directory '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scrapy/templates/project', created in: /Users/lewisgong/PycharmProjects/project_scrapy/project_scrapy/demo You can start your first spider with: cd demo scrapy genspider example example.com
用Pycharm打开该项目,项目结构如下:
在middlewares.py中添加一个类,来实现PhantomJS处理爬虫请求。
要点介绍:首先需要下载PhantomJS驱动,需要在系统环境变量中设置PhantomJS的路径,否则运行时会找不到PhantomJS。或者在初始化时也可以手动指定PhantomJS的路径。
应对懒加载:有些网站需要进行滚动条滚动来加载其余数据,针对此,我们将窗口尽量设置大一点,再用PhantomJS进行滚动。
from selenium import webdriver from selenium.webdriver.support import ui from scrapy.http import HtmlResponse import time class JavaScriptMiddleware(object): def process_request(self, request, spider): if spider.name == "demo": driver = webdriver.PhantomJS() # 指定浏览器 print ("PhantomJS is starting...") driver.set_window_size(1000, 10000) # 尽量将窗口设置大一些,以应对某些网站使用懒加载 driver.get(request.url) js1 = "var q=document.documentElement.scrollTop=5000" driver.execute_script(js1) # 模仿用户操作,下拉滚动条 time.sleep(1) body = driver.page_source print ("PhantomJS is visiting "+request.url) return HtmlResponse(driver.current_url, body=body, encoding='utf-8', request=request) else: return
如果需要进行网页点击等操作,可以加上等待事件,等待某个元素加载完毕之后再将PhantomJS得到的数据返回给爬虫处理。举个简单的例子:
wait = ui.WebDriverWait(driver, 15) driver.find_element_by_xpath('//*[@id="prd_tbox"]/li[3]/a').click() wait.until(lambda driver: driver.find_element_by_xpath('//*[@id="j-comment-section"]/div/div[1]/div[1]/div[1]/span'))
先设定一个等待事件,等待时间为15ms,然后通过xpath找到这个按钮并进行点击,然后可以等待某个元素加载,加载成功即继续,不成功可以进行其他处理。
至此我们的中间件PhantomJS就算设置完了,还需要在Scrapy的配置中启用就可以了,非常方便。
配置MongoDB的传输通道piplines.py
连接所需要的库为pymongo,MongoDB的官方库。连接MongoDB所需要的所有配置都存在settings里面,这里将其调用出来直接使用就好了。
通过配置pipelines,可以将爬取到的item全部存入MongoDB中。
from scrapy import log import pymongo from scrapy.conf import settings class DemoPipeline(object): def __init__(self): try: connection = pymongo.MongoClient(host=settings['MONGODB_SERVER'], port=settings['MONGODB_PORT']) db = connection[settings['MONGODB_DB']] db.authenticate(name=settings['MONGODB_USER'], password=settings['MONGODB_PWD']) self.connection = db[settings['MONGODB_COLLECTION']] print("MonoDB connection established...") except Exception as e: print("An exception occurred when try to connect to MongoDB: "+str(e)) def process_item(self, item, spider): computer = dict(item) self.connection.insert(computer) log.msg("Computers added to MongoDB database", _level=log.INFO, spider=spider) return item
Scrapy的settings.py配置文件
要点介绍:需要设置HTTP headers中的user-agent,让爬虫看起来更像是一个浏览器的请求。
可以在这里配置MongoDB需要使用的地址、数据库名、用户等,当然也可以用其他方法来减少噪音的hardcode
启用刚刚定义的DemoPipelines
禁用Scrapy内置中间件,启用我们自己定义的中间件。
禁用robot.txt,某些网站会根据robot.txt来指定搜索引擎蜘蛛只抓取指定的内容,或者是禁止搜索引擎蜘蛛抓取网站的部分或全部内容。
BOT_NAME = 'demo' SPIDER_MODULES = ['demo.spiders'] NEWSPIDER_MODULE = 'demo.spiders' USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5' MONGODB_SERVER = 'MongoDB server address' MONGODB_PORT = 27017 MONGODB_DB = 'DB_name' MONGODB_USER = 'DB_user' MONGODB_PWD = 'DB_password' MONGODB_COLLECTION = 'Collection_name' ITEM_PIPELINES = { 'gm_computer.pipelines.DemoPipeline': 300, } DOWNLOADER_MIDDLEWARES = { 'gm_computer.middlewares.JavaScriptMiddleware': 543, 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, # 禁用内置的中间件 } # Obey robots.txt rules ROBOTSTXT_OBEY = True
设置items.py
item即你要抓取的一个元素的数据集合,最后会通过pipelines将item写入数据库。import scrapy from scrapy import Field, item class DemoItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() demo = Field() #与爬虫中的item['demo']对应
爬虫处理翻页
现在我们的基本配置以及全部完成了,剩下的就是要写一个爬虫来处理数据了!在spider目录下新建一个爬虫demo.py# -*- coding: utf-8 -*- from scrapy.spiders import CrawlSpider from scrapy.http import Request from scrapy.selector import Selector from gm_computer.items import DemoItem # 如果Pycharm出现红线,忽略即可 """ 设置页面编码 """ import sys reload(sys) sys.setdefaultencoding('utf-8') class ComputerSpider(CrawlSpider): name = "demo" start_urls = ["https://my.oschina.net/lewisgong"] allowed_domains = ["oschina.net"] # 允许访问的域名,如果访问的页面不是在该域名下,则爬虫终止 def parse(self, response): """ 处理页面数据 """ item = DemoItem() selector = Selector(response) item['demo'] = selector.xpath('xpath of element').extract()[0] yield item if True: # 判断是否有下一页,条件自己定义 yield Request(url="下一页的地址", callback=self.parse) # 将下一页的地址传回parse()继续抓取数据
到这里就结束啦,本人也是个小菜鸟,在不断学习中,欢迎指教。
相关文章推荐
- 用Python+Selenium+PhantomJS实现采集动态数据的小爬虫
- java实现的highcharts与ajax结合动态实时获取数据更新图表
- 实现FusionChart动态获取数据(三)
- python结合selenium获取XX省交通违章数据的实现思路及代码
- [Python爬虫] Selenium+Phantomjs动态获取CSDN下载资源信息和评论
- 基于Python,Selenium和PhantomJS实现动态页面爬取
- Hibernate中通过JPA entity graph的方式实现动态数据获取
- 实现FusionChart动态获取数据(一)
- Python 爬虫 PhantomJs 获取JS动态数据
- Python 爬虫 PhantomJs 获取JS动态数据
- selenium+ phantomjs实现动态网页爬取
- 动手实现扩展属性为对象动态添加获取数据(续)
- 动手实现扩展属性为对象动态添加获取数据
- java实现的highcharts与ajax结合动态实时获取数据更新图表
- 实现FusionChart动态获取数据(二)
- 动态获取后台最新数据的一个实现方法
- Jquery 实现动态添加table tr 和删除tr 以及checkbox的全选 和 获取添加TR删除TR后的数据
- [安卓] 9、线程、VIEW、消息实现从TCP服务器获取数据动态加载显示
- selenium配合phantomjs实现爬虫功能,并把抓取的数据写入excel
- myOpenChord 界面数据后台线程获取,动态显示实现