数据采集(六):scrapy爬取搜狗微信新闻+selenium模拟鼠标点击
2017-08-01 10:41
369 查看
scrapy框架解析
scrapy是一个流行的爬虫框架,为什么要用它呢?前面我们已经通过xpath或beautifulsoup实现了爬虫,scrapy又有什么不同?我在初步理解了这个框架之后,感觉它很灵活,很强大。使用beautifulsoup库我们可以很方便的实现单个爬虫,最后的结果写进了一个字典。但是当考虑一个项目中有多个爬虫,或者需要将最后的结果保存进json、csv文件,mysql数据库、mogodb数据库,或者网页是包含js的动态网页时,请使用scrapy。
下面这张图可以帮助我们宏观地把握这个框架:
绿色的箭头代表了工作过程的流向。scrapy内部有一个调度器,它根据提供的初始链接,去下载网页内容。有一些动态的网页不能直接通过request下载,比如需要点击鼠标,下拉滑块等操作,html才能加载完整,这个时候需要用到DownloaderMiddlewares,即下载器中间件。
当网页下载之后,然后会通过response交给爬虫来处理了。爬虫会返回两类内容,一类是爬取的结果,它封装在items里,items可以类比一个字典,是一个scrapy自定义的数据结构,把它交给Item Pipeline处理;一类是url链接,这是个更深层次的网页,遵循同样的流程,把它抛给调度器,重复这个过程。后面解析代码时会详细看到这个过程的实现。
SpiderMiddlewares我暂时还没怎么接触到。
Item Pipeline负责将item保存在文本文件或者数据库。
可以看到框架中每个部分分工明确,可以很方便的定制。
爬取搜狗微信新闻
下面以爬取搜狗微信新闻为例,对scrapy一探究竟。网址为搜狗微信频道。我们的目的是爬取首页所有新闻的标题、发布时间以及发布者。可以看到首页新闻仅有20条,点击“加载更多内容”之后,其余的新闻才能显现出来。在scrapy中怎么着手呢?建立一个空的scrapy项目之后,我们会发现里面有items.py、middlewares.py、pipelines.py、settings.py、还有一个spiders文件夹。这是都
4000
是我们施展拳脚的地方,当然一些爬虫项目不会用到全部,那剩余的各种,我们都不用管,交给框架处理就好。
确定爬取字段
首先明确爬取的字段—title、time、post_user。这个在items.py中指定。# -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # http://doc.scrapy.org/en/latest/topics/items.html import scrapy class WxnewsItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() title=scrapy.Field() time=scrapy.Field() post_user=scrapy.Field()
编写爬虫
然后在spiders文件夹中建立一个py文件,比如wxnews_spider.py,文件名字是无所谓的。在py文件中,要写一个符合规范的类,比如:# -*- coding:utf-8 -*- import scrapy from wxnews.items import WxnewsItem class WxnewsSpider(scrapy.Spider): name = 'wxnews' start_urls = [ 'http://weixin.sogou.com' ] def parse(self, response): news_href_list=response.xpath('//ul[@class="news-list"]/li/div[2]/h3/a/@href') #print response.url for href in news_href_list: url=response.urljoin(href.extract()) yield scrapy.Request(url,callback=self.parse_news) def parse_news(self, response): title=response.xpath('.//div[@id="page-content"]/div/h2/text()').extract_first() time=response.xpath('.//div[@id="page-content"]/div/div[1]/em[1]/text()').extract_first() post_user=response.xpath('.//a[@id="post-user"]/text()').extract_first() #print title.strip() #print time.strip() #print post_user.strip() #print " " #yield {'title':title, # 'time':time, # 'post_user':post_user # } news=WxnewsItem() news['title']=title.strip() news['time']=time news['post_user']=post_user yield news
解释一下上述代码,首先需要导入item类,然后写一个爬虫类体。它是一个派生类,name是爬虫名字、start_url是爬虫开始的url,都是从父类继承的属性。parse也是继承函数,程序会默认调用。在程序中我们也写了一个自定义的解析函数parse_news。它和parse相同,都接受response对象。都可通过yield抛出两类对象,一类是item,一类就是request。request通过callback指定了对获取后的网页内容采用何种解析方法,比如下句:
yield scrapy.Request(url,callback=self.parse_news)
yield类比return,不同之处在于执行yield之后会继续执行函数体中后续代码。
可以看到在parse函数中,一样是通过xpath定位并解析出想要的元素。
将结果写入文件
到这一步,我们就该考虑怎么把结果保存进文本文件。如果是保存到csv文件或json文件中,那么很方便的是,我们在pipelines中可以什么也不用写,即可完成这一功能。只需要在命令行中执行爬虫时,指定一个文件。如下所示scrapy crawl wxnews -o result.csv
wxnews是爬虫名字,result.csv是结果文件。
获取需要将结果写入数据库,那么需要在pipelines中写一个自定义的process_item函数,包括怎么连接数据库,和对数据库增删改查的操作。
编写下载中间件,模拟鼠标点击
在本例中,也并非最简单的例子,因为,我们需要模拟鼠标点击的动作,使网页加载出完整内容。我们需要在middlewares.py的process_request函数写这一功能。它涉及到下载这一步骤,接受request,返回response,所以叫下载中间件。详细代码如下:#-*- coding:utf-8 -*- from selenium import webdriver from scrapy.http import HtmlResponse import time from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from random import choice class SeleniumMiddleware(object): def process_request(self, request, spider): click_page_url="http://weixin.sogou.com" if request.url==click_page_url: driver = webdriver.PhantomJS() try: driver.get(request.url) driver.implicitly_wait(3) time.sleep(5) look_more=".//div[@class='jzgd']/a" for n in range(4): driver.find_element_by_xpath(look_more).click() # 数据由js来控制,点击后加载数据 time.sleep(5) true_page = driver.page_source driver.close() return HtmlResponse(request.url,body = true_page,encoding = 'utf-8',request = request,) except: print "get news data failed" else: return None
上述代码引入一个模块叫selenium,它用来模拟浏览器以及鼠标的各种行为。这里的鼠标行为即点击某个元素,比如这里是“look_more”。PhantomJS叫无头浏览器,它是selenium里的,当然selenium里可以模拟很多浏览器,比如chrome,火狐等。无头浏览器不同点是它不需要渲染出花花绿绿的页面,名字起的很到位。从代码中可以看到,模拟了浏览器请求页面以及超时等待等操作。
爬取结果
所讲的例子包含的工作量就是这些。运行之后,看看我们成果:总共获取约100条数据,因为每页20条新闻,鼠标点击4次,首页新闻可全部加载完。
相关文章推荐
- 自动点击王-一款神奇的模拟软件-包含数据采集-投票刷票-post机-后台鼠标键盘模拟-验证码识别
- 全能自动点击王 包含数据采集-刷票-post机-后台鼠标键盘模拟-验证码识别
- selenium--unittest定位元素内容为空时模拟鼠标点击的方法
- selenium--unittest定位元素内容为空时模拟鼠标点击的方法
- 4000 4,selenium 模拟鼠标操作 (悬浮和左键点击)
- 从点击事件看微信小程序的数据传递
- 使用JS或jQuery模拟鼠标点击a标签事件代码
- PhantomJS 和Selenium模拟页面js点击
- 还是一个鼠标点击td变成input,失去焦点更新数据库
- 【Java】在JTable中设置鼠标监听器,点击操作对应数据
- 自动化测试 : 模拟鼠标点击
- php模拟post提交数据,用处很多,可用来网站的采集,登陆等等
- 使用firefox和selenium模拟点击js获取更多评论
- ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml) 用javascript在客户端删除某一个cookie键值对 input点击链接另一个页面,各种操作。 C# 往线程里传参数的方法总结 TCP/IP 协议 用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图 (转)值得学习百度开源70+项目
- 模拟鼠标点击
- 超宽带信号高速数据采集记录存储回放系统—采样率高达5GSPS,模拟带宽3GHZ!
- 【名风自动点击王】支持前台和后台鼠标键盘模拟游戏生活好帮手|IP网页自动点击器
- [python]windows下模拟鼠标点击和键盘输入
- Scrapy 分布式数据采集方案
- curl模拟自动登陆&采集网页数据