在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 我觉得有可能是个文件头之类的,这个错误我在编程过程中出现过好几次,一直没有彻底弄明白过,只能先用这种方法把问题避开。这个方法源于另一篇文章。感谢此作者为我节省了很多时间。