1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > python爬评论_Python笔记--菜鸟爬虫(爬微博评论)-Go语言中文社区

python爬评论_Python笔记--菜鸟爬虫(爬微博评论)-Go语言中文社区

时间:2019-02-07 18:13:42

相关推荐

python爬评论_Python笔记--菜鸟爬虫(爬微博评论)-Go语言中文社区

第一次爬虫就是爬微博的评论(爬虫—只要能看就能爬)

准备工作:

Python2.7(看个人习惯)、FireFox浏览器(看个人习惯)

Python安装什么的网上一大堆教程,我不班门弄斧了

FireFox感觉我个人感觉好用一点,比起全英版的Chrome

from selenium import webdriver#这是重中之重咯,现在微博的评论都是有动态加载的,我是靠这个去控制鼠标行为的

import time#休眠(效果你懂的)、记录当前时间

import xlwt#写入文件用的

上面那几句只是记录一下需要用到的包

url = '******'#自己随便找个微博链接试试吧,不过如果你配置不够,不建议你找5w以上的,超级卡,这些还是得看配置的,网页需缓存

driver = webdriver.Firefox()#打开浏览器

driver.get(url)#输入链接并加载

time.sleep(10)#休眠一下,我不是机器人

此时此刻,如果你把网络断了,然后拉到页面最底下,会发现,评论显示是不全的,然后还有一个“正在加载”的东东显示,而且这个玩意如果你不拉下去是不会帮你加载的,如果你直接爬,你只能爬前面几十条。

重新联网,你会看到又加载N条评论出来,这时候我们就弄一个js,控制鼠标帮我们把页面拉到最底下,使得最大限量的评论显示出来

js="var q=document.documentElement.scrollTop=100000"#10w是指拉到位置值为10w的地方,当然,一般来说,刚加载的网页不会那么长,不然缓存都直接使电脑奔溃

for i in range(10):#重复个10次(当然可以设置更多,但其实一般1-2次就OK了),防止页面没加载完

driver.execute_script(js)#调用js,将页面拖到底

time.sleep(2)

你以为这样评论就显示全了?

其实还没,你看看是不是有一个“查看更多”按钮,点一下,好像多了几十条,但是还有这个按钮,那就是代表还有更多评论没显示,爬虫的中心是什么,能看的就能爬,你都还没看到,那就是还不能爬了,所以,继续点吧。

手点好像有点慢,有点累,那就换程序控制点击吧

接下来就是通过定位“查看更多”这个按钮来使全部的评论都显示出来

Selenium库中定位的方式有很多种(诸如什么id定位、name定位、class定位等等,我这篇爬虫用了其中几个,各有各的好处,但还是要亲自试试吧)

PS:原本想转载一篇关于Selenium中的定位方式,但是不知道会不会侵权什么的,就自己去百度吧,我最多在文章末尾介绍一下我用到的几个定位方式

#查看更多直至全部显示

for i in range(20):

while (1):#只要循环体能运行就一直循环(因为不知道需要点击多少次“查看更多”,所以会使用while(true)循环

try:#尝试,若报错,执行except体

driver.find_element_by_class_name("more_txt").click()#通过class name定位,重复点解“查看更多”

time.sleep(0.8)#休眠

except:

break#结束循环

time.sleep(2)

既然已经全部都显示了,那就开始爬吧,每一条评论呢我们能看见的基本都是评论用户昵称、评论内容、评论时间、评论的回复人数,评论的点赞数(我个人是觉得这2个没什么必要),然后看不见的就是评论用户的链接、评论用户的ID。

###如果想要进阶的话可以爬更深层次的评论用户的信息(地址、性别、微博等级、关注数、粉丝数、微博量、生日、个人简介等等),不过这个就看个人需要了。

我这里就只爬了评论用户昵称、评论用户的链接、评论用户的ID、评论内容、评论时间,按需求选择就是了

try:

#获取评论总数

#通过xpath获取页面显示的评论数(一般与实际不相符,或多或少)

comment_sum=driver.find_element_by_xpath("/html/body/div[1]/div/div[4]/div/div[2]/div[1]/div/div/div/div/div[2]/div/ul/li[3]/a/span/span/span/em[2]").text

comment_sum = int(comment_sum)#转换类型,str→int

#爬取评论并储存列表

for i in range(100000):#循环10w次(微博评论超过5w页面基本都会崩溃,电脑配置问题,如果高一点的,可以把循环设置更高,以求爬全部评论)

tem=[]#临时存储列表

k=str(i+1)#转换类型,字符串合并需要str类型

#a:评论用户昵称+评论内容,通过xpath获取,xpath从网页复制

a=driver.find_element_by_xpath("/html/body/div[1]/div/div[4]/div/div[2]/div[1]/div/div/div/div/div[4]/div/div[2]/div[2]/div/div/div["+k+"]/div[2]/div[1]").text#评论用户名+评论

a_1=a.split(u":")[0]#截取评论用户昵称

a_2=a[a.find(u":")+1:len(a)]#截取用户评论内容

#d:评论用户url地址,通过xpath获取

d=driver.find_element_by_xpath("/html/body/div[1]/div/div[4]/div/div[2]/div[1]/div/div/div/div/div[4]/div/div[2]/div[2]/div/div/div["+k+"]/div[2]/div[1]/a[1]").get_attribute('href')#评论用户地址

#e:评论用户ID,,通过xpath获取,然后截取

e=driver.find_element_by_xpath("/html/body/div[1]/div/div[4]/div/div[2]/div[1]/div/div/div/div/div[4]/div/div[2]/div[2]/div/div/div["+k+"]/div[2]/div[1]/a[1]").get_attribute('usercard').split("=")[1]#评论用户id

#b:评论时间,因为一条评论具有多种展现形式,而评论时间是最受影响的一个,目前只找到用try嵌套的方式进行获取(xpath可能因为评论的内容及评论是否具有回复的情况而改变)

try:

b=driver.find_element_by_xpath("/html/body/div[1]/div/div[4]/div/div[2]/div[1]/div/div/div/div/div[4]/div/div[2]/div[2]/div/div/div["+k+"]/div[2]/div[2]/div[2]").text

except:

try:

b=driver.find_element_by_xpath("/html/body/div[1]/div/div[4]/div/div[2]/div[1]/div/div/div/div/div[4]/div/div[2]/div[2]/div/div/div["+k+"]/div[2]/div[3]/div[2]").text

except:

b=driver.find_element_by_xpath("/html/body/div[1]/div/div[4]/div/div[2]/div[1]/div/div/div/div/div[4]/div/div[2]/div[2]/div/div/div["+k+"]/div[2]/div[4]/div[2]").text

#将评论用户昵称、评论内容、评论用户url、评论用户ID、评论时间及所属KOL添加到临时存储列表tem中

tem.append(a_1)

tem.append(a_2)

tem.append(d)

tem.append(e)

tem.append(b)

#没爬取1w条评论会print出一次用户昵称(第N万个评论用户的昵称)

if int(k)%10000 == 0:

print tem[0]

time.sleep(1)

#将临时存储列表添加到评论存储列表中

res_PL.append(tem)

except:#如果i超过了评论大楼的最高楼层,则执行下面内容,表示该链接已爬完,并且print出-实际爬取数量 页面显示评论数 总爬取数据

print u"该链接已爬完"+" "+str(i)+" "+str(comment_sum)+" "+str(len(res_PL))#

driver.quit()#退出页面

最后就是写入文件了,写入文件有很多种方法,不过感觉最好用还是to_csv

columns_name = [u'评论用户昵称',u'评论内容',u'评论用户链接',u'评论用户ID',u'评论时间']#定义表头

res_tem = pd.DataFrame(columns=columns_name,data=res_PL)#定义表内容

res_tem.to_csv(u"C:\Users\Administrator\Desktop\评论用户数据.csv",encoding='utf_8_sig')#写入CSV文件并保存在桌面

回头说一下,我这里主要用到的定位方式:

1、class定位:find_element_by_class_name(self, name)

通过定位网页的class元素属性,只要你想定位的有class属性,你就可以通过class_name来定位,但是要注意一个页面中可能会存在多个同样class_name的元素,所以这种方式相对适合页面仅此一个class属性的元素

我们可以通过页面的开发者工具(点一下F12)来找到你所需的class_name。

2、xpath定位:find_element_by_xpath(self, xpath)

通过定位网页中的XML地址来定位元素,存在唯一性,就是只有你的xpath精准,不可能定位错,而且可通过迭代重复定位,获取所有评论的信息。若评论间的xpath存在差异,则需要通过尝试(try)获取所需内容

点击这个,然后找到我们需要获取的内容

鼠标放在需定位内容上,然后可以在右边看到信息对于的页面源码

然后右击页面源码→选择“复制”→选择“复制xpath”,然后就能得到页面信息的xpath,通过找到每条信息的逻辑,用迭代的方式找出各个评论的消息并获取

写在最后:

1、这是一个相对较笨的方法,但菜鸟是这样的啦,不要介意太多;

2、或者你们会问,为什么有些评论已评论的评论(拗口吗,希望你能懂)没被爬取,我只能说这是其中的一个缺陷吧,但其实这部分评论不多,忽略的话弊端应该不大(下次我更新一篇,然后那篇是把这部分也爬了的);

3、这个方法不仅笨,而且还有点慢(慢是和休眠时间有一定关系),1k条评论大概10分钟,1w条评论大概1小时,10w。。。我电脑配置不好,5w的量已经略卡了;

4、或者你们想问,微博好像封了我IP,我爬不了了,那我只能说你运气不太好,我这么就还没被封,要不你把休眠时间弄长一点试试,再不行就只能模拟登陆或者用代理了,但这个太高级,我还不会,去问度娘吧

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。