推特爬虫爬取用户id和所有tweets(免登录,不使用api)所有代码都已经发布在github上:https://github.com/smityliu/spider这次做的一个项目中涉及人物画像,做人物画像中兴趣属性很关键的一点就是要收集足够多的人物数据,基础工作就是进行爬虫的书写,收集数据集。对于一个社交网络来说,这里最大最实用的数据集合就是用户发布的帖子,因为里面的东西会关联到个人的兴趣爱好,甚至工作生活,从中做主题提取就可以大致的看出来人物在这个社交网络上所体现出来的一个兴趣属性。经久不衰的话题----白帽子安全条款:不用爬虫爬取个人隐私!所以我对于社交网络的选择标准:1.国外社交网络-----推特;2.只爬取网站上公开发布的用户信息。由于模拟登录过于频繁还是会被网站封ip和账号,因此就想能不能实现免登录状态下的爬虫,爬取用户数据。
用户id爬取
推特上用来标识用户身份的标志可不是用户名,因为用户名是可以重复的,比如我搜索tolly这个用户,会发现有好多用户名叫tolly的。
但是他们的用户id却是唯一的:
红色框中的就是用户id。即使用户名相同,id也不会相同,那么我们来看一下用户主页:这里随便找了一个国外小哥的主页,发现其实域名就是twitter.com + 用户id。
因此我们首先要通过爬虫获取到用户id,才能进行下一步的数据爬取:查询的api接口为:https://twitter.com/search?f=users&vertical=default&q=smity&src=unkn
q参数输入的就是在你要查询的昵称大致是什么样子,也就是你在搜索框输入的东西。
如果我们直接requests请求这个连接,那么返回的东西就会是一堆带着html标签的文本,很难看。所以我们必须分析用户名在哪种标签里,id在哪种标签里。
上图就是爬取出来的带有很多html标签的文本,我们可以看到用户名是在
这样提取之后,我们的内容就被简化为如下效果:
会发现还是有很多杂质在里面
提取步骤三因此我们继续做如下处理,首先分析提取的东西结构,里面含有很多标签和unicode编码字符,@其他用户的语句,以及一些固定的url,我们都将其去除或者替换。
pattern =re.compile(r']+>|pic.twitter.com/.*|http(.*?) |',re.S)
line = re.sub(pattern ,'',line)
line = re.sub(''' ,'\'',line)
line = re.sub('<','',line)
line = re.sub('&','&',line)
line = re.sub('"','"',line)
line = re.sub(r'^@(.*?) @(.*?) |^@(.*?) ','',line)
这样的到的就是我们干净的文本,每一行的内容都是一个tweets。
最后加上我们的新请求构造,取下一个max_position的页面内容
tweets=requests.get(url+'&max_position='+text_json["min_position"]+'&reset_error_state=false',proxies=proxies)
整体代码如下:
import requests
import json
import re
import sys
#返回一个json,里面有min-position
#这个地方可以用下面这个url获取到最开始的max_position,当前页面用的是max_position,然后响应包json里的min_position就是下一页的max_position,循环获取,直到没有min_position。
url="https://twitter.com/i/profiles/show/"+sys.argv[1]+"/timeline/tweets?include_available_features=1&include_entities=1"
proxies={'http':'127.0.0.1:10809','https':'127.0.0.1:10809'}
tweets=requests.get(url,proxies=proxies)
tweets.encoding="utf-8"
#这个地方一定要写入一行content作为标题,不然后面的lda.py会报错
with open("./text.txt",'w',encoding='utf-8') as f:
f.write("content"+'\n')
with open("./text.txt",'a',encoding='utf-8') as f:
text_json=json.loads(tweets.text)
while(text_json["min_position"]):
print(text_json["min_position"]+'\n')
#items_html里面有些地方有回车符,导致正则不能提取帖子文本,一定要先去掉所有回车符
text=text_json["items_html"].replace('\n','')
#这个地方应该要用取得形式,从标签里面先取,然后再删除,版本一是直接删除所有标签这样做代码没有重用性而且去除很麻烦
content=re.findall(r'data-aria-label-part="0">(.*?)',text)
for line in content:
#把多余标签,pic.twitter.com和url去掉
pattern = re.compile(r']+>|pic.twitter.com/.*|http(.*?) |',re.S)
line = re.sub(pattern ,'',line)
line = re.sub(''' ,'\'',line)
line = re.sub('<','',line)
line = re.sub('&','&',line)
line = re.sub('"','"',line)
line = re.sub(r'^@(.*?) @(.*?) |^@(.*?) ','',line)
if(len(line)):
#continue
f.write(line+'\n')
tweets=requests.get(url+'&max_position='+text_json["min_position"]+'&reset_error_state=false',proxies=proxies)
text_json=json.loads(tweets.text)
print("finish work")
代码运行后,每爬取一个页面就会返回下一个页面的max_position,如果没有下一页,就会结束爬取。
可以提前用ctrl+c结束脚本运行,不论是否爬取完毕,都会在同目录下生成一个text.txt文件用于存放爬取的数据。下一章节我们将继续分析如何利用这些爬取的数据进行主题提取。
相关实验:
Python爬虫-基础:
http://www.hetianlab.com/expc.do?ec=ECID80b9-d088-4e0c-8f80-0d57b2a9e89c
(了解爬虫的基本原理,对爬虫有简单的认识)
别忘了投稿哦
大家有好的技术原创文章
欢迎投稿至邮箱:edu@heetian.com
合天会根据文章的时效、新颖、文笔、实用等多方面评判给予200元-800元不等的稿费哦
有才能的你快来投稿吧!
了解投稿详情点击——重金悬赏 | 合天原创投稿涨稿费啦!