我在上学期的数据挖掘课程三次大作业的最后一个题目选了这个题目,数据源为搜狗微信搜索(weixin.sogou.com),这个站除了首页的热门文章,其他页面都以ajax的形式加载。之前写的爬虫都是简单的页面内容抓取,这次遇到的主要挑战有:抓取ajax异步传输的数据,用PhantomJS解析以js加载的数据。
只抓取首页热门文章的代码比较简单:
- # -*- encoding: utf-8 -*-
- from pyspider.libs.base_handler import *
- from pyquery import PyQuery as pq
- import re
- class Handler(BaseHandler):
- crawl_config = {
- "headers": {
- "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36)", #配置用户代理,模拟普通用户
- }
- }
- def __init__(self):
- self.base_url = 'http://weixin.sogou.com/'
- @every(minutes=24 * 60)#每天执行一次
- def on_start(self):
- self.crawl(self.base_url,callback=self.index_page, fetch_type='js')
- @config(age=10 * 24 * 60 * 60)#有效期10天
- def index_page(self, response):
- for each in response.doc('h4 > a').items():
- self.crawl(each.attr.href, callback=self.detail_page, fetch_type='js')
- @config(priority=2)#调度优先级
- def detail_page(self, response):
- return {
- "链接": response.url,
- "标题": response.doc('#activity-name').text(),
- "日期": response.doc('#post-date').text(),
- "作者": response.doc('#post-user').text(),
- "内容": response.doc('#js_content').text(),
- "公众号二维码": response.doc('#js_pc_qr_code_img').attr('src'),
- "阅读数": response.doc('#sg_readNum3').text(),
- "点赞数": response.doc('#sg_likeNum3').text(),
- }
由于公众号文章的页面中的公众号二维码、阅读数、点赞数等都用ajax异步加载,虽然可以用chrome的开发者模式查看XHR文件的链接再按照链接的规律写代码,但这样做比较麻烦。我就直接采用PhantomJS渲染带JS的页面,这样就可以将爬虫要抓取的网页完整的抓取下来以便对需要的数据进行抓取。
phantomjs官网:http://phantomjs.org/download.html
下载二进制安装包到vps,然后解压安装即可。 并在“self.index_page”和“self.detail_page”后面添加:, fetch_type='js'即可渲染带js的页面了。
要抓取其他分类的文章则需要通过浏览器的”审查元素“→”network“→”XHR“ 然后点击加载ajax的按钮即可查看ajax的链接(如“爱生活”这个分类的ajax链接为:http://weixin.sogou.com/pcindex/pc/pc_6/pc_6.html)。
分页文章也可以采用这个方法抓取(如:http://weixin.sogou.com/pcindex/pc/pc_6/num.html num为分页的页码,可以采用循环增加num来抓取多页文章)。既然安装了phantomjs,不妨使用phantomjs渲染页面,再用模拟点击按钮的方法实现分页抓取:
- def on_start(self):
- self.crawl('http://weixin.sogou.com',
- fetch_type='js', js_script="""
- function() {
- setTimeout("$('#look-more').click()", 1000);
- setTimeout("$('#look-more').click()", 2000);
- setTimeout("$('#look-more').click()", 3000);
- }""", callback=self.index_page)
look-more为加载下一页按钮的id,1000、2000、3000分别为延时。
具体实现代码详见:https://github.com/leisu168/weixingongzhonghao
顺便分享几个几个降低爬虫被封的措施:
一、降低抓取的频率,模拟人为浏览
二、修改user-agent:
1、伪装成搜索蜘蛛:
a)百度蜘蛛ua:Mozilla/5.0 (compatible;Baiduspider/2.0; +http://www.baidu.com/search/spider.html)
b)360蜘蛛:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1; 360Spider(compatible; HaosouSpider; http://www.haosou.com/help/help_3_2.html)
2、伪装成普通PC用户:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
三、使用代理IP
四、将爬虫架设在多IP或多拨的VPS上