time微博「sptime微博」( 三 )


另外 , 还有一些需要特别注意的因素
* 微博分为原创微博和转发微博
* 按照发布时间至当前时间的差距 , 在页面上有”MM分钟前”、”今天HH:MM”、”mm月dd日 HH:MM”、”yyyy-mm-dd HH:MM:SS”等多种显示时间的方式* 手机版新浪微博一个页面大约显示10条微博 , 所以要注意对总共页数进行记录以上几点都是细节 , 在爬虫和提取的时候需要仔细考虑 。
0x04. 编码
1.爬取用户微博
本项目开发语言是Python 2.7 , 项目中用了一些第三方库 , 第三方库可以用pip的 *** 添加 。
既然程序自动登录的想法被验证码挡住了 , 想要访问特定用户微博页面 , 只能使用者提供cookies了 。
首先用到的是Python的request模块 , 它提供了带cookies的url请求 。
import request
print request.get(url, cookies=cookies).content使用这段代码就可以打印带cookies的url请求页面结果 。
首先取得该用户微博页面数 , 通过检查网页源码 , 查找到表示页数的元素 , 通过XPath等技术提取出页数 。
页数
项目使用lxml模块对html进行XPath提取 。
首先导入lxml模块 , 在项目里只用到了etree , 所以from lxml import etree
然后利用下面的 *** 返回页数
def getpagenum(self):
url = self.geturl(pagenum=1)
html = requests.get(url, cookies=self.cook).content# Visit the first page to get the page number.
selector = etree.HTML(html)
pagenum = selector.xpath('//input[@name="mp"]/@value')[0]
return int(pagenum)
接下来就是不断地拼接url-访问url-下载网页 。
需要注意的是 , 由于新浪反爬机制的存在 , 同一cookies访问页面过于“频繁”的话会进入类似于“冷却期” , 即返回一个无用页面 , 通过分析该无用页面发现 , 这个页面在特定的地方会出现特定的信息 , 通过XPath技术来检查这个特定地方是否出现了特定信息即可判断该页面是否对我们有用 。
def ispageneeded(html):
selector = etree.HTML(html)
try:
title = selector.xpath('//title')[0]
except:
return False
return title.text != '微博广场' and title.text != '微博'
如果出现了无用页面 , 只需简单地重新访问即可 , 但是通过后期的实验发现 , 如果长期处于过频访问 , 返回的页面将全是无用页面 , 程序也将陷入死循环 。为了避免程序陷入死循环 , 博主设置了尝试次数阈值trycount , 超过这个阈值之后 *** 自动返回 。
下面代码片展示了单线程爬虫的 ***。
def startcrawling(self, startpage=1, trycount=20):
attempt = 0
try:
os.mkdir(sys.path[0] + '/Weibo_raw/' + self.wanted)except Exception, e:
print str(e)
isdone = False
while not isdone and attempttrycount:
try:
pagenum = self.getpagenum()
isdone = True
except Exception, e:
attempt += 1
if attempt == trycount:
return False
i = startpage
while i = pagenum:
attempt = 0
isneeded = False
html = ''
while not isneeded and attempttrycount:
html = self.getpage(self.geturl(i))
isneeded = self.ispageneeded(html)
if not isneeded:
attempt += 1
if attempt == trycount:
return False
self.savehtml(sys.path[0] + '/Weibo_raw/' + self.wanted + '/' + str(i) + '.txt', html)print str(i) + '/' + str(pagenum - 1)
i += 1
return True
考虑到程序的时间效率 , 在写好单线程爬虫之后 , 博主也写了多线程爬虫版本 , 基本思想是将微博页数除以线程数 , 如一个微博用户有100页微博 , 程序开10个线程 , 那么每个线程只负责10个页面的爬取 , 其他基本思想跟单线程类似 , 只需仔细处理边界值即可 , 在此不再赘述 , 感兴趣的同学可以直接看代码 。另外 , 由于多线程的效率比较高 , 并发量特别大 , 所以服务器很容易就返回无效页面 , 此时trycount的设置就显得更重要了 。博主在写这篇微博的时候 , 用一个新的cookies , 多线程爬***场测试了一下爬取北京邮电大学的微博 , 3976条微博全部爬取成功并提取博文 , 用时仅15s , 实际可能跟cookies的新旧程度和 *** 环境有关 , 命令行设置如下 , 命令行意义在项目网址里有说明python main.py _T_WM=xxx; SUHB=xxx; SUB=xxx; gsid_CTandWM=xxx u bupt m 20 20爬取的工作以上基本介绍结束 , 接下来就是爬虫的第二部分 , 解析了 。由于项目中提供了多线程爬取 ***  , 而多线程一般是无序的 , 但微博博文是依靠时间排序的 , 所以项目采用了一种折衷的办法 , 将下载完成的页面保存在本地文件系统 , 每个页面以其页号为文件名 , 待爬取的工作结束后 , 再遍历文件夹内所有文件并解析 。

推荐阅读