python微博爬虫编写

  因为最近要做一个爬到微博中所有用户发表的微博以及所有用户的点赞、评论以及转发操作,因此学习了一下如何使用python编写微博的爬虫。为了防止后续再次用到,再加上之前在一个奇怪的地方定下了新年要写微博的新年目标,因此,特地记录了下来。
  首先声明一下环境,电脑装的windows10系统,准备使用python2.7+scrapy这两样东西拼起来搞一个微博的爬虫。

环境的配置

python的安装

  首先是python的下载和安装,考虑到网络上资料有限,个人比较怂的选择了较为古老的python2.7,而不是较新的python3。下载地址:python2.7。安装起来比较简单,一路无脑next即可。
  之后需要稍微对环境变量进行一下配置,从而方便后续使用。具体方法:
  添加了一个 PYTHON_HOME的系统变量,值是C:\Program Files (x86)\python27;C:\Program Files (x86)\python27\Scripts,再之后修改PATH这一系统变量,把刚刚的%PYTHON_HOME%这个变量加到最后。
  现在,直接在cmd里面输入python就有了如下输出:
  python安装成功效果
  至此,python27安装成功。

IDE的选择

  没有IDE我为什么要用windows。python自带的ide实在是不好用,我随便选择了一个ide使用:Wing IDE。下载和破解链接这里就不贴了,现用现查。可喜可贺的是Wing IDE居然支持vim的快捷键,然而并不支持自定义的vimrc。事实证明,即使可以也尽量不要修改默认的快捷键,不然都是泪啊。现在一般的vim用起来都难受了。

scrapy的安装

  说道爬虫,大部分人都会用到python。对于里面的道理大体就是因为可用的库比较多。相对于python自带的urllib和urllib2的库,第三方框架scrapy用起来更为的强大和方便。
  安装scrapy相对于安装python2.7要曲折的多。首先是直接安装。打开cmd,之后使用如下命令(如果你配好了环境变量的话),如果你幸运地话,就有一定可能可以直接安装成功。

pip.exe install scrapy

  成功后的结果是有一个很明显的成功信息。忘了截图了。
  然而,我并不是一个十分幸运地人。整个安装过程中,我主要遇到了三个问题,记录下来方便后续看。对不起观众的是由于错误已经被解决,所以错误消息已经残缺不全了。

权限不足

  这个最为简单,就是说权限不足不可以在c盘中的一个目录里面创建一个文件,从而导致安装失败。解决的也很简单,直接使用管理员权限运行cmd即可。

没有vs的库

  这个问题已经比较恶心了。问题如下:

Microsoft Visual C++ 9.0 is required  (Unable to find vcvarsall.bat)

  经过一番搜索发现了解决,因为python2.7所带的pip是和vs2010一个年代的东西,因此用的是vc++9.0的东西们。解决方法有两个,一个是升级pip,我怂,没敢搞。
  另一个方法就是我用的。因为我的机子上已经装了vs2014的库,所以只需要将vc++9指向实际的vc++14的位置即可。方法如下,修改系统变量,添加如下一项。
  系统变量
  当然前提是你的系统变量里面有那个14的东西。方便复制我打印一遍VS90COMNTOOLS%VS140COMNTOOLS%
  如果还不行可以参考这个链接尝试照着下载一下:别人家处理这个问题的博客

没有xmllib

问题如下:

 c:\users\f\appdata\local\temp\xmlXPathInitqjzysz.c(1) : fatal error C1083: Cannot open include file: 'libxml/xpath.h': No such file or directory
  *********************************************************************************
  Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?
  *********************************************************************************
  error: command 'C:\\Users\\f\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\VC\\Bin\\cl.exe' failed with exit status 2

  顺便一提,当时我因为vs的问题弃疗在Ubuntu上头捯饬python的时候就是因为碰到了这个问题所以又回到了windows平台下。
  解决方法其实更加简单,查询了stackoverflow,如下操作即可:

easy_install lxml

  至此,scrapy安装成功,在cmd命令行下输入scrapy,可以看到类似如下信息。
  可喜可贺可喜可贺

其他问题

  后来我在看scrapy的文档的时候发现我还是naive了,其实上面还没有成功,也不是很好复制。正确的安装方法应该参考如下链接,ssl我之前不知什么时候安装过,而没有安装pywin32的后果也在后续运行scrapy shell的时候显示了出来。这件事情启示我们,先看文档再动手。官方文档中的安装指南看这里

迭代一,保存每个用户的首页

  为了熟悉一下环境,做了一个简单的迭代一,主要目的就是爬取每一个用户的首页到预期用户id对应的文件中。

入门文档

  scrapy的官网为我们提供了比较详细的文档,特别可喜可贺的是居然还有中文文档,简直省劲。在开始写之前,建议先花费一两个小时吧入门文档看一下,了解一下最基础的架构,什么事spider,什么事item,什么事pipeline,如何创建项目等。具体的见一下两个链接:初窥入门教程

选择爬取网页:wap>电脑版

  这是我在某一个大腿的知乎上面看到的一个重要的经验,要写一个网站的爬虫时,优先尝试wap版本该网站,这个版本一般css少,网页简单,表单清晰,没有ajax,总之特别好。比如就微博而言,众所周知的weibo.com的网页复杂无比,还有花式的js脚本。而如果选择了wap版本的weibo.cn,审查源代码可以看到,非常的简单明了。
  其实原文上面说的是wap>移动版>电脑版,但是对于wap和移动版之间的区别我还是不是很懂,暂时的理解是wap版相当于好多年前的2G版应用,移动版相当于3G版应用,自然前者要好很多。如有不对,后续再修改

对微博url的简要分析

  在微博中,每个用户都有一个唯一的uid,作为该用户的标示。当你访问某一用户首页的时候,地址的url通常如下:http://weibo.cn/u/***,这里的*就是该用户的uid,有十个数字组成。打个比方:http://weibo.cn/u/1421647581(笛子大大是个好大大)。
  因此,这次迭代的任务比较简单,主要是熟悉环境,爬取形如weibo.cn/u/%uid%的网页,并保存到uid的同名文件中即可。

编写spider

  因为这只是测试一下scrapy的简要操作,因此我们就不使用item和pipeline了,只是单纯的编写一个简单的spider来进行爬取。

spider的大致流程

  对于一个spider,其操作流程大致如下,首先进行初始化,之后对于其成员变量start_urls中的每一个字符串,调用make_request_from_url方法,将其变成一个requesst,并且开始从这个request进行爬取。
  当这个request的网页数据下载完成后,会调用这个request所对应的回调函数对爬取结果进行处理。每一个回调函数都可以返回两种值:
  一种是request的list,这种情况下,scrapy会自动把这些request添加到待爬取的request中,继续进行爬取。默认情况下,似乎是一种类似于bfs的添加方式,也可以通过调整设置调节为类似dfs的方式。(待验证
  另一种是item的list。item的详细定义见官方文档,若返回item的list,则会将每一个item都是用pipeline存储到合适的位置。

初始化

  知道spider的大致流程后就可以开始编写了。首先是一些必要的初始化操作。代码如下:

    uidFileName = "D:\\uid.txt"
    name = 'weiboSpider'
    def __init__(self, category=None, *args, **kwargs):
        super(WeiboSpider, self).__init__(*args, **kwargs)
        self.header = {
            'Connection' : 'keep-alive',
            'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36',
            'Accept-Encoding' : 'gzip, deflate, sdch',
            'Accept-Language' : 'zh-CN,zh;q=0.8',
        }
        try:
            dataFile = open(self.uidFileName, "r")            
        except:
            sys.stderr.write("please check the uid file exists!")
            exit()
        try:
            self.cookie = eval(open("D:\\cookie.txt", "r").readline())
        except:
            sys.stderr.write("please check the uid file exists!")
            exit()
        self.start_urls = ['http://weibo.cn/u/3433941822']
        for line in dataFile:
            lineUids = eval(line.split("\t")[1]).keys()
            for lineUid in lineUids:
                self.start_urls.append("http://weibo.cn/u/"+lineUid)                

  其中,最重要的是两个部分的初始化,一个是name,这是scrapy框架所要求的为每一个spider都要有一个唯一的name。这样,后续的命令行命令中才可以使用scrapy crawl %name%来调用相应的spider进行爬取;第二个是start_urls,及爬虫的入口地址,就是最初需要开始爬取的网址们。
  这里我已经实现从一个奇妙的地方获得了许许多多的用户的uid,并保存到了文件中,直接从文件中读取即可。(关于遍历文件那个快这一争端性问题,请见一个不是特别底层的讨论
  至于cookie和header,主要是后续用来模拟登陆和浏览器访问使用的,请见下一节。

设置header和cookie,模拟登陆

  对于weibo.cn这个wap页面来说,不登录是不会让你访问任何一个人的主页的。因此,我们需要首先模拟登陆。这一步我偷了个懒,直接使用浏览器进行登录,之后使用fiddle进行抓包,再之后把这个包中的header和cookie拷贝了出来,在后续直接强行设死,从而方便装作浏览器的样子进行登录。写死header和cookie的代码见init(这里还有一点问题,我是用相对路径跑不起来,不是很懂),使用时候的代码如下:

    def make_requests_from_url(self, url):
        return Request(url, headers=self.header, cookies=self.cookie)

  这里就是用了我们之前说的make_requests_from_url,设置了一下header和cookie。(这里的cookie不算在header里面,我之前urllib用惯了在这里坑了好久。)这里还有一个小问题,如果cookie改变了会如何。文档上面说scrapy会根据setcookie自动设置,但是我这里make_request_from_url直接写死了会不会死

parse

  最后是一个简单版本的parse,这里实在太简单了,就是直接把获得的response保存到相应的文件中即可。代码如下:

    def parse(self, response):    
        filename = response.url.split("/")[-1]
        print response.url
        open("D:\\scrapytmp"+filename+".html", "wb").write(response.body)

  之后,在项目路径下(及和scrapy.cfg这一文件在同一层目录下的地方打开cmd,运行scrapy crawl weiboSpider,即可看到我们的爬虫正确的运行了起来。打开d盘,就可以看到新保存的文件了。

未完待续

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章