新浪微博爬取笔记(3):wap端爬取用户微博列表 ,微博转发列表,用户信息

时间:2022-04-26 08:34:59

wap端登陆成功后,就可以安心开始爬取数据了。我这次需要的数据是:

(1)用户的近期1000条微博,需要:微博id,转发量,发布时间

(2)某条微博的转发列表,需要:转发人,转发时间

(3)某个用户的关注数,粉丝数,微博数,最近100条微博的平均转发量

 


 

相比模拟登陆,爬数据的工作就简单很多。但需要注意几个坑,一边做一边总结如下:

##爬微博列表##

(1)虽然目前wap端每页加载的微博数貌似是固定的,但其实是不固定的!爬一页的时候一定要先读取当页的实际微博数量。

    有时候每页显示5条,有时候10条。。。

(2)“发布时间”和“来自xxx”基本在一个tag下,但是这个tag中可能还嵌套了tag,获取字节的时候要注意这点。

(3)我设置的每页爬取完后time.sleep(2),目前爬100页还没有出现问题。(爬100页实际用了5分半)(代理这时候又不好用了,试了10几个都不行,可能是校园网限制,所以自己的ip一定要小心使用。。)

 

得到的一条数据是:

M_CdF7juKD8 转发[43] 04月17日 10:28 来自微博 weibo.com 

清理数据:

用正则表达式提取数字等, 参考http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html

 

 


 

##爬转发列表##

转发列表每页间隔time.sleep(1.5)

爬了20多条某用户1000-1500转发的微博的转发列表,爬了两个多小时,一直都好好的, 然后突然找不到标签,丢失。。以为是BeautifulSoup的解析问题,换用lxml,但是lxml.etree的text()找不到字符串不知道是为什么。第二天重又运行了下BeautifulSoup实现的,居然没问题了。。难道是因为连续爬太多对方服务器会对这个ip发出警告?。。

真是提心吊胆啊。

第二天,同样又是爬了20多条后出现了问题。换了个号,好了。。

 

除了需要转发人和转发时间,还需要转发人前面的那些帐号。weibo.cn转发列表中的一条是这样的:

<div class="c"><a href="/u/1788790161">攒钱攒RP准备看控的某路</a>: //<a href="/n/%E6%88%98%E6%96%97%E5%90%A7%E5%A4%A7%E5%AE%AB%E5%B0%8F%E6%88%98%E5%A3%AB_KK">@战斗吧大宫小战士_KK</a>://<a href="/n/%E5%BF%83%E5%AE%BD%E6%89%8D%E8%83%BD%E4%BD%93%E6%A3%92">@心宽才能体棒</a>:mmm //<a href="/n/XXX_%E5%95%A6%E5%95%A6%E5%95%A6">@XXX_啦啦啦</a>://<a href="/n/%E5%B0%8F%E7%8C%AA%E5%A7%90%E5%A7%90zz">@小猪姐姐zz</a>: 太需要了!&nbsp;<span class="cc"><a href="/attitude/CdL8OB3ZZ/add?uid=2165379597&amp;rl=1&amp;do=rt&amp;st=aa3027">赞[0]</a></span><span class="ct">&nbsp;04月18日 01:49&nbsp;来自 iPhone客户端 </span></div>

可以看到,除了转发人,也就是第一个<a>中的href所用的是uid的域名(当然有些自主改了域名),后面的都是微博昵称,也就是大家说的ID。新浪微博生成的uid和昵称没有算法上的转换关系,不像微博的id和mid可以用算法转化,因此想通过其中一个获得另一个,就必须访问服务器,也就是访问网页查找元素这种方式。

 

通过‘/n/XXXXXXX’获得微博昵称,用url编码转化一下即可。


 

 ##爬用户信息##

{用户uid(已知) 用户ID 关注 转发 前xx条微博的转发数}

 


 

都是用BeautifulSoup定位元素,比如“爬用户信息”部分的主要代码:

 1 for line in urlFile.readlines():
2 user1 = line.split()[0]
3 print user1
4 user2 = user1.split('/')[-1]#some adaption to the txt name
5 userUrl = 'http://weibo.cn' + user1
6 userFile = open("%sInfo.txt"%user2,'a')
7 req = urllib2.Request(userUrl, headers = headers)
8 resp = urllib2.urlopen(req)
9 soup = BeautifulSoup(resp.read())
10 #htmlTree = HTML.fromstring(resp.read())
11
12 #ID = htmlTree.xpath("/html/body/div[2]/table/tbody/tr/td[2]/div/span[1]")
13 ID_area = soup.find('div', attrs={"class":'u'})
14 IDli = ID_area.find('div',attrs = {"class":'ut'}).find('span', attrs={"class":'ctt'}).strings
15 ID = [string for string in IDli][0].split()[0].encode('utf-8')
16 ID_fo = ID_area.find('div', attrs = {'class':'tip2'})
17 #.strings is a generator, not iter(?)
18 li =[string for string in ID_fo.stripped_strings]
19 ID_follow = re.compile('\w+').findall(li[1])[0]
20 ID_follower = re.compile('\w+').findall(li[2])[0]
21 userFile.write(str(user1) +' '+str(ID)+' '+str(ID_follow)+' '+str(ID_follower)+' ')
22 print 'part 1 finished'
23 time.sleep(1.5)
24
25 ##then crawl for 20 pages for repo
26 for page in range(1, 21):
27 pageUrl = userUrl + '?page=%s'%page
28 post_num = len(soup.find_all('div', attrs = {"id":re.compile("M_"),"class":'c'}))
29 for post in range(0, post_num):
30 repoNum = soup.find_all('div', attrs = {"id":re.compile("M_"),"class":'c'})[post].find_all('div')[-1].find_all('a')[-3].string.encode('utf-8')
31 repoNum = re.compile('\w+').findall(repoNum)[0]
32 userFile.write(str(repoNum)+' ')
33 print page
34 time.sleep(1.5)
35 print 'part 2 finished'
36 userFile.close()