1. 爬虫项目介绍
爬虫首先基于python scrapy 框架,使用了随机用户代理和IP代理等反爬技巧,将爬取到的微博领域数据,各领域榜单博主信息和博主的微博信息分别存入的mysql数据库对应的表格中。
查看爬虫完整代码请移步GitHub:QiliWu/sinaweibo_spidergithub.com
2. 爬虫逻辑
2.1 获取微博领域信息
首先爬取了V影响力榜列出的微博全部领域名称及对应的各领域微博榜单链接。
2.2 获取各领域榜单博主信息
分别进入各领域排行榜页面(以互联网为例),抓取4月 月榜 排名前100的博主相关信息。
分析上述网页发现,博主信息是通过单独请求json文件获得的。
请求的url地址为:
最后面__rnd字段的值起始为请求的时间戳
请求方式为POST, 发送的表单内容为:
其中type, date,domainId字段都可以在主页网址(互联网榜)的源码中获取到。
根据上述分析编写的请求代码如下:
def parse_domain_url(self, response):
match = re.match(r'.*?"currentDate":(\d+).*?"pagetype":"(\d+)".*?"domainId":(\d+).*', response.text, re.S)
date = match.group(1)
type = match.group(2)
domainId = int(match.group(3))
post_data = {'type': type,
'period': 'month',
'date': date,
'pagesize': '100', #一次请求100条博主信息
'page': '1',
'domainId': str(domainId),
'_t': '0'}
post_url = 'http://v6.bang.weibo.com/aj/wemedia/rank?ajwvr=6&__rnd={0}'
headers = {'Content-Type':'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest',
'Referer':response.url}
yield FormRequest(url=post_url.format(int(time.time()*1000)),
method='POST',
formdata=post_data,
headers=headers,
callback=self.parse_domain_detail,
meta={'domainId':domainId})
2.3 获得博主个人主页和发表微博信息
获得每个博主的信息(包括博主的昵称,id, 粉丝数,关注数,微博数,性别,地址等信息)后,进入该博主的微博主页,爬取该博主最近的前60条微博信息(包括微博内容,发表日期,转发/点赞/评论数等信息)。
这里,请求每个博主主页url时,需要带上cookie信息,cookie的内容是固定的,可以通过手动操作浏览器请求一次随便一个博主主页获得。
cookies = {'SINAGLOBAL': '6766495850665.497.1501852555183',
'SUB': '_2AkMtfS1zf8NxqwJRmP0TzmziboRyywzEieKbIdyoJRMxHRl-yT9kqlEitRB6XNyh2MtIX_786TcqrC_9KhHomc2jrviO',
'SUBP': '0033WrSXqPxfM72-Ws9jqgMF55529P9D9WWTsTi36AWHDVnU2ITVs6AB',
'UM_distinctid': '1621ce4477d161-044b65bce7d5c1-b353461-100200-1621ce4477ecc',
'UOR': 'news.youth.cn,widget.weibo.com,www.baidu.com',
'_s_tentry': '-',
'Apache': '811175706409.3062.1526986486457',
'TC-Page-G0': '1e758cd0025b6b0d876f76c087f85f2c'}
yield Request(url=data['profile_url'],
cookies=cookies,
callback=self.parse_user_weibo,
meta={'useritem':useritem})
随后,分析博主微博主页发现,发表的微博内容信息又是通过单独请求json文件获得的。其中data键对应的值是一个字符串格式的html内容,里面包含了约15条微博的具体信息。
获取json文件的url为:
https://weibo.com/p/aj/v6/mblog/mbloglist?ajwvr=6&domain=100505&is_hot=1&pagebar=0&pl_name=Pl_Official_MyProfileFeed__20&id=1005051577826897&script_uri=/fenng&feed_type=0&page=1&pre_page=1&domain_op=100505&__rnd=1527403062839
url很长,其中domain,pl_name, page_id , script_uri字段值都可以通过分析博主微博主页的源码获得。而rnd同样为时间戳,pre_page字段为页码,逐渐递增的。
请求url的方式为GET。
所以请求的代码为:
def parse_user_weibo(self, response):
useritem = response.meta['useritem']
...
...
#请求微博内容的json数据
domain = re.match(r".*CONFIG\['domain'\]='(\d+?)'.*", response.text, re.S).group(1)
pl_name = re.match(r'.*domid":"(Pl_Official_MyProfileFeed__\d+)".*', response.text, re.S).group(1)
page_id = domain + useritem['uid']
script_uri = '/u/'+useritem['uid']
weibo_url = 'https://weibo.com/p/aj/v6/mblog/mbloglist?ajwvr=6&domain={0}&is_hot=1&pagebar={1}&pl_name={2}&id={3}&script_uri={4}&feed_type=0&page=1&pre_page=1&domain_op={0}&__rnd={5}'
#微博内容是json, 每页15条,爬取前60条
for pagebar in range(4):
yield Request(url=weibo_url.format(domain, pagebar, pl_name, page_id, script_uri, int(time.time()*1000)),
callback=self.parse_weibo_detail)
请求到json文件后,将data对应的值其转化为scrapy的Selector子类,即可使用css或者xpath选择器来从中获取想要的信息。
def parse_weibo_detail(self, response):
r = json.loads(response.text)
data = r['data']
selector = Selector(text=data)
weibolist = selector.css('div[action-type="feed_list_item"]')
for weibo in weibolist:
weiboitem = WeiboInfoItem()
...#详细内容见github源码
...
yield weiboitem
3. 爬虫代理设置
新浪微博的方法还是很厉害的,同一个ip多次请求后很快就被封了。所以本爬虫项目使用了随机更换user-agent和ip地址的方法来反爬。
3.1 随机user-agent
编写一个RandomUserAgentMiddleware中间件,使用fake-useragent第三方包生成一个UserAgent()实例,为每个ip随机生成一个user-agent。
3.2 随机ip
首先在蘑菇ip代理上都买付费的代理ip,生成一个包含5个ip的api链接,然后通过GetIP类对api链接返回的json文件进行处理,提取ip信息保存到mysql数据库中。然后scrapy在每次生成请求时都会向数据库随机请求一个有效的ip(通过请求http://ip.chinaz.com/getip.aspx网址来事先判断数据库ip的有效性)。
如此不停地变换ip地址发送请求,基本上不会被反爬。
4. 爬取结果
爬取到的结果通过twisted框架提供的方法异步保存到mysql数据库,微博领域,博主和微博内容信息分别存到weibotopic, topicuser, weiboinfo三个表格中。
weibotopic (共38个领域):
topicuser(共3648个用户,有些领域榜单上没有100个用户):
weiboinfo(共115740条微博)
5. 小结
以上就是基于V影响力榜单爬取新浪微博信息的爬虫介绍,具体代码在github上,欢迎查看,交流指教。
接下来,在文章wala qili:python爬取和分析新浪微博(二):微博影响力榜用户数据和微博内容的信息挖掘及可视化展示zhuanlan.zhihu.com
中,针对爬取到的数据信息,使用numpy, pandas对其进行了简单的统计分析,并通过可视化工具 matplotlib, wordcloud和basemap对分析结果进行了可视化展示。分析结果还是包含很多有意思的结论,欢迎继续关注。