爬虫之scrapy-splash——scrapy+js渲染容器

简介


scrapy作为爬虫利器,我就不多说了。
常见的结合js的爬虫,一般用来扒取网页动态内容,就是通过操作js获取渲染的内容。
现在大部分网站都是ajax+json获取数据的方式,所以,大家习惯性一上来爬虫,第一件事就是抓包,然后找规律抓数据。当然有时候,接口加密算法很复杂,短时间内很难破解,通过js抓取内容相对容易,这时候结合js的爬虫就能比较直接地达到目的,当然数据抓取效率不如直接抓接口来得快。

结合js的爬虫


目前,我知道的结合js的爬虫有以下3种。(有补充的,麻烦大神留言。)

  1. selenium+webdriver(如firefox,chrome等)。这要求你系统有对应浏览器,并且过程中要全程开浏览器。说白了,就是你通过浏览器能看到啥,就能抓到啥。一般遇到特别复杂的验证码时,这个方法是有必要的,当然,开着浏览器爬虫的效率可想而知。
  2. selenium+phantomjs。PhantomJS是一个WebKit,他的使用方法和webdriver一样,但是他不需要开浏览器,你可以直接跑在无需GUI的linux服务器上,这点很赞。
  3. scrapy-splash。这个和以上两种方法比,优势有以下几点。
  • splash作为js渲染服务,是基于Twisted和QT开发的轻量浏览器引擎,并且提供直接的http api。快速、轻量的特点使其容易进行分布式开发。
  • splash和scrapy融合,两种互相兼容彼此的特点,抓取效率较好。
  • 虽然目前只有英文文档,但写的已经很详细了,仔细阅读便能快速开发。

本文主要介绍第三种爬虫方案的使用。

安装


关于安装,网上有很多了,请自行谷歌。
这里建议遵循官网安装方式。但注意因为splash服务需要依托docker。而docker在Ubuntu的安装方法,需要仔细看下文档,并注意Ubuntu版本。

启动


安装docker之后,官方文档给了docker启动splash容器的命令(docker run -d -p 8050:8050 scrapinghub/splash),但一定要查阅splash文档,来了解启动的相关参数。
比如我启动的时候,就需要指定max-timeout参数。因为我操作js时间较长时,很有可能超出默认timeout时间,以防万一我设定为3600(一小时),但对于本来js操作时间就不长的的同学,注意不要乱设定max-timeout。
docker run -d -p 8050:8050 scrapinghub/splash --max-timeout 3600

使用


关于scrapy-splash的使用教程主要来自scrapy-splash githubsplash官方文档。除此之外,给出我最近写的一个scrapy-splash的代码。该代码主要实现js页面不断切换,然后抓取数据,下面是该代码的核心部分。因为,splash使用lua脚本实现js的操作,看下官方文档和这个代码,基本可以入门splash了。

fly_spider.py

class FlySpider(scrapy.Spider):
    name = "FlySpider"
    house_pc_index_url='xxxxx'

    def __init__(self):
        client = MongoClient("mongodb://name:pwd@localhost:27017/myspace")
        db = client.myspace
        self.fly = db["fly"]

    def start_requests(self):
        

        for x in xrange(0,1):
            try:
                script = """
                function process_one(splash)
                    splash:runjs("$('#next_title').click()")
                    splash:wait(1)
                    local content=splash:evaljs("$('.scrollbar_content').html()")
                    return content
                end
                function process_mul(splash,totalPageNum)
                    local res={}
                    for i=1,totalPageNum,1 do
                        res[i]=process_one(splash)
                    end
                    return res
                end
                function main(splash)
                    splash.resource_timeout = 1800
                    local tmp=splash:get_cookies()
                    splash:add_cookie('PHPSESSID', splash.args.cookies['PHPSESSID'],"/", "www.feizhiyi.com")
                    splash:add_cookie('FEIZHIYI_LOGGED_USER', splash.args.cookies['FEIZHIYI_LOGGED_USER'],"/", "www.feizhiyi.com" )
                    splash:autoload("http://cdn.bootcss.com/jquery/2.2.3/jquery.min.js")
                    assert(splash:go{
                        splash.args.url,
                        http_method=splash.args.http_method,
                        headers=splash.args.headers,
                    })
                    assert(splash:wait(splash.args.wait) )
                    return {res=process_mul(splash,100)}
                    
                end
                """
                agent = random.choice(agents)
                print "------cookie---------"
                headers={
                    "User-Agent":agent,
                    "Referer":"xxxxxxx",
                }
                splash_args = {
                    'wait': 3,
                    "http_method":"GET",
                    # "images":0,
                    "timeout":1800,
                    "render_all":1,
                    "headers":headers,
                    'lua_source': script,
                    "cookies":cookies,
                    # "proxy":"http://101.200.153.236:8123",
                }
                yield SplashRequest(self.house_pc_index_url, self.parse_result, endpoint='execute',args=splash_args,dont_filter=True)
                # +"&page="+str(x+1)
            except Exception, e:
                print e.__doc__
                print e.message
                pass

如果想更深地利用scrapy-splash,请研究splash官方文档,另外,欢迎留言交流学习。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容