爬虫第二弹——隐网爬虫指南,AcFun评论爬取教程



爬虫第一弹:利用Scrapy爬取1905电影网

啊啊啊!!!!写完没保存!!!!还得重新写一遍!!!!!好气啊!!!!!!

前言

AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面。
因此现在有很多网站都是用Ajax进行前后端数据交互的。

然而正是因为很多网站使用Ajax导致网络爬虫无法跟进。
这时就需要我们针对不同的网站定制爬虫。

AcFun 评论数据传输分析

页面分析

首先测试爬去使用Ajax传输数据的网站的效果,我们以AcFun视频为例。

打开页面http://www.acfun.tv/v/ac2860882,下图所示是当前页面是直接在浏览器打开的效果,可以看到红色框内的就是当前页面的评论。

这里写图片描述

下图是通过爬虫爬去该网页的结果,可以看到红色框内并没有评论,因为当前评论没有传过来。
这里写图片描述

寻找数据

我们现在利用Chrome浏览器的Developer Tools寻找数据。
打开原页面,在当前页面上邮件选择检查,进入到Developer Tools后选择Network。在Network中选择XHR(数据),再刷新当前页面,从左侧列表中寻找评论数据(注意:数据需要从右侧栏需选择Preview栏才可以看到)
这里写图片描述

构建评论url

我们发现评论是通过comment_list_json.aspx页面发送过来的。
这时我们点开该页面的Query String Parameters查看参数

这里写图片描述

这个json请求一共有两个参数,且其含义也不难理解

于是这个json请求的url如下所示:
http://www.acfun.tv/comment_list_json.aspx?contentId=%1¤tPage=%2

得知url的形式后就可以开始写爬虫了!

程序

理论上所有图灵完备的语言都可以写爬虫,但为了效率与保持心情愉悦我推荐用Python。

我平时喜欢用Scrapy或urllib2写,Scrapy适合中到大规模且爬取逻辑简单的爬虫,如果遇到非常复杂或者是非常简单的爬虫,那么就需要用urllib2定制了,想学Scrapy可以看我的爬虫第一弹

本文致力于一切从简的思想,使用urllib2写一个小的Demo.

#encoding=utf-8

import urllib2
import json

def get_page(url):
    try:
        timeout = 5
        request = urllib2.Request(url)
        #伪装HTTP请求
        request.add_header('User-agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36')
        request.add_header('connection','keep-alive')
        request.add_header('referer', url)
        # request.add_header('Accept-Encoding', 'gzip') # gzip可提高传输速率,但占用计算资源
        response = urllib2.urlopen(request, timeout = timeout)
        html = response.read()
        #if(response.headers.get('content-encoding', None) == 'gzip'):
        # html = gzip.GzipFile(fileobj=StringIO.StringIO(html)).read()
        response.close()
        return html
    except Exception as e:
        print 'URL Request Error:', e
        return None

def anlysis_json(json_data):
    s = json.loads(json_data)

    # 如果爬取失败,则返回
    if not s['success']:
        return

    # commentList中保存评论的编号
    # commentContentArr中是以 c + 评论编号 作为索引的
    # 因此需要先从commentList中获取编号
    comment_id_list = s['data']['commentList']

    for id in comment_id_list:
        id = 'c'+str(int(id))
        if s['data']['commentContentArr'][id]['isDelete']:
            continue

        print str(s['data']['commentContentArr'][id]['content']).encode('utf-8')

if __name__ == '__main__':
    contentID = 2860882     # 页面ID
    currentPage = 1         # 评论页ID
    basic_url = 'http://www.acfun.tv/comment_list_json.aspx?contentId=%d¤tPage=%d'

    url = basic_url % (contentID,currentPage)

    json_data = get_page(url)
    anlysis_json(json_data)

结果如下图所示
这里写图片描述

总结

爬虫是一门很有意思的技术,学习曲线就像y=x的图像一样,好入门,坡度也不陡,但想要十分精通也很难。我能力有限,只是想将知识分享出来大家一起讨论进步。

爬虫下一弹我打算做Scrapy简单网站的登陆,也不知道啥时候能做出来,慢慢做吧。