在github上找到了一个twitter的爬虫,试了下,修改了其中一个有关编码的问题,可以抓取一定数量的twitter
https://gist.github.com/TVFlash/cccc2808cdd9a04db1ce
代码如下
from bs4 import BeautifulSoup, NavigableString
from urllib2 import urlopen
#Note: must be a public profile
print "Twitter username:"
user = raw_input()
endpoint = "https://twitter.com/%s"
f = urlopen(endpoint % user)
html = f.read()
f.close()
soup = BeautifulSoup(html, 'html.parser')
tweets = soup.find_all('strong', {'class': 'fullname js-action-profile-name show-popup-with-id'})
for i in range(0,len(tweets)):
user = tweets[i].contents[0]
action_tag = soup('span', {'class': 'username js-action-profile-name'})
show_name = action_tag[i].contents[1].contents[0]
twit_text = soup('p', {'class': 'js-tweet-text'})
message = ""
for nib in twit_text[i]:
if isinstance(nib, NavigableString):
message += nib
else:
message += nib.text
print user, "@", i, show_name, message.replace(u'\xa0', u'')
下面进行解释:
第1行:从bs4中导入两个类。BeautifulSoup中存储整个html文档并且可以在其中搜索,NatigableString存储html中特定的text,但也支持某些搜索的功能。
第2行:从urllib2中导入urlopen方法,用于发送请求到url并返回html文档
第5-6行:输入要抓取的用户名
第8行:输入twitter网址
第10-12行:生成最终的目标url并使用urlopen方法,将下载的html文档读取到html变量中,然后关闭对象。urlopen.read只能使用一次,第二次再调用此方法时返回空值,所以也就相当于只能迭代一次的迭代器。
第14行:根据文档生成用于检索的BeautifulSoup对象。
第16行:找到所有class属性为 'fullname....with-id' 的strong标签,每个strong标签都唯一对应一条推文,因为实际上这就是每条推文上作者的姓名,当然这样提取出来的不仅包括用户发表的推文,也包括了用户转推的推文。
第18行:对所有这样的标签进行遍历
循环内:
第19行:将tweets中当下元素的内容赋值为user
第21行:提取出所有的动作发出者,这里不仅能提取出发送推文的作者,也能提取出转推者,在twitter页面上,就是一个用户名前加上'@'的标签,这行其实应该放到循环外,在这里重复了。
第22行:show_name提取出当下推文发送者的姓名unicode字符串
第24行:提取出推文内容,这行也应该放到循环外,
第26-31行:将当下推文的从不同的string或tag中抽取并粘合在一起,第28行中,如果判断为真,那说明此元素就是text(因为实质上NavigableString就是多了一些功能的string对象),如果为假,则说明这只是一个包含text的tag。
第33行:依次输出发送此条推文的动作发出者,原作者,以及推文内容。此处如果不把 u‘\xa0’ 替换为空的话,会报UnicodEncodeError,但现在看替换成这样并不影响输出推文内容,所以这个 \xa0 我觉得有可能是个文件头之类的,这个错误我在编程过程中出现过好几次,一直没有彻底弄明白过,只能先用这种方法把问题避开。这个方法源于另一篇文章。感谢此作者为我节省了很多时间。