[Python爬虫] Selenium爬取新浪微博客户端用户信息、热点话题及评论 (上)

标签: python selenium 新浪微博 | 发表时间:2016-04-24 07:29 | 作者:Eastmount
出处:http://blog.csdn.net

一. 文章介绍


前一篇文章" [python爬虫] Selenium爬取新浪微博内容及用户信息"简单讲述了如何爬取新浪微博手机端用户信息和微博信息。
用户信息:包括用户ID、用户名、微博数、粉丝数、关注数等。
微博信息:包括转发或原创、点赞数、转发数、评论数、发布时间、微博内容等。


它主要通过从文本txt中读取用户id,通过"URL+用户ID" 访问个人网站,如柳岩:
         http://weibo.cn/guangxianliuya
因为手机端数据相对精简简单,所以采用输入用户的形式依次爬取各个明星的信息。
而这篇文章主要爬取客户端的微博信息,相对信息更多;同时登录微博后在输入框中搜索热点话题,然后依次爬取微博信息和对应的评论。这篇文章的输出如下图所示:


PS:注意这篇文章爬取微博内容和评论的时候,由于它是动态加载的,故爬取失败,但思考可以参考。后面下篇会进行解决,如果实在不行只能爬取手机端的信息了。


二. 核心代码


这篇文章打算先给出完整代码,再进行讲解的方法:
1.LoginWeibo(username, password) 登录微博,自动输入用户名和密码
2.VisitPersonPage(user_id) 访问跟人网站,获取个人信息,通过如下网址访问柳岩:
      http://weibo.cn/guangxianliuyan
3.GetComment(key) 获取微博信息及评论信息,获取输入框按钮进行搜索
获取微博内容评论是注意翻页功能

# coding=utf-8

"""  
Created on 2016-04-24 @author: Eastmount
功能: 爬取新浪微博用户的信息及微博评论
网址:http://weibo.cn/ 数据量更小 相对http://weibo.com/
"""    

import time            
import re            
import os    
import sys  
import codecs  
import shutil
import urllib 
from selenium import webdriver        
from selenium.webdriver.common.keys import Keys        
import selenium.webdriver.support.ui as ui        
from selenium.webdriver.common.action_chains import ActionChains

#先调用无界面浏览器PhantomJS或Firefox    
#driver = webdriver.PhantomJS(executable_path="G:\phantomjs-1.9.1-windows\phantomjs.exe")    
driver = webdriver.Firefox()
wait = ui.WebDriverWait(driver,10)

#全局变量 文件操作读写信息
inforead = codecs.open("SinaWeibo_List_best_1.txt", 'r', 'utf-8')
infofile = codecs.open("SinaWeibo_Info_best_1.txt", 'a', 'utf-8')

#********************************************************************************
#                            第一步: 登陆weibo.cn 
#        该方法针对weibo.cn有效(明文形式传输数据) weibo.com见学弟设置POST和Header方法
#                LoginWeibo(username, password) 参数用户名 密码
#********************************************************************************

def LoginWeibo(username, password):
    try:
        #输入用户名/密码登录
        print u'准备登陆Weibo.cn网站...'
        driver.get("http://login.sina.com.cn/")
        elem_user = driver.find_element_by_name("username")
        elem_user.send_keys(username) #用户名
        elem_pwd = driver.find_element_by_name("password")
        elem_pwd.send_keys(password)  #密码
        #elem_rem = driver.find_element_by_name("safe_login")
        #elem_rem.click()             #安全登录

        #重点: 暂停时间输入验证码(http://login.weibo.cn/login/ 手机端需要)
        time.sleep(20)
        
        elem_sub = driver.find_element_by_xpath("//input[@class='smb_btn']")
        elem_sub.click()              #点击登陆 因无name属性
        time.sleep(2)
        
        #获取Coockie 推荐资料:http://www.cnblogs.com/fnng/p/3269450.html
        print driver.current_url
        print driver.get_cookies()  #获得cookie信息 dict存储
        print u'输出Cookie键值对信息:'
        for cookie in driver.get_cookies(): 
            #print cookie
            for key in cookie:
                print key, cookie[key]
                    
        #driver.get_cookies()类型list 仅包含一个元素cookie类型dict
        print u'登陆成功...'
        
        
    except Exception,e:      
        print "Error: ",e
    finally:    
        print u'End LoginWeibo!\n\n'


#********************************************************************************
#                  第二步: 访问个人页面http://weibo.cn/5824697471并获取信息
#                                VisitPersonPage()
#        编码常见错误 UnicodeEncodeError: 'ascii' codec can't encode characters 
#********************************************************************************

def VisitPersonPage(user_id):

    try:
        global infofile       #全局文件变量
        url = "http://weibo.com/" + user_id
        driver.get(url)
        print u'准备访问个人网站.....', url
        print u'个人详细信息'
        
        #用户id
        print u'用户id: ' + user_id

        #昵称
        str_name = driver.find_element_by_xpath("//div[@class='pf_username']/h1")
        name = str_name.text        #str_name.text是unicode编码类型
        print u'昵称: ', name
        
        #关注数 粉丝数 微博数 <td class='S_line1'>
        str_elem = driver.find_elements_by_xpath("//table[@class='tb_counter']/tbody/tr/td/a")
        str_gz = str_elem[0].text    #关注数
        num_gz = re.findall(r'(\w*[0-9]+)\w*', str_gz)
        str_fs = str_elem[1].text    #粉丝数
        num_fs = re.findall(r'(\w*[0-9]+)\w*', str_fs)
        str_wb = str_elem[2].text    #微博数
        num_wb = re.findall(r'(\w*[0-9]+)\w*', str_wb)
        print u'关注数: ', num_gz[0]
        print u'粉丝数: ', num_fs[0]
        print u'微博数: ', num_wb[0]

        #文件操作写入信息
        infofile.write('=====================================================================\r\n')
        infofile.write(u'用户: ' + user_id + '\r\n')
        infofile.write(u'昵称: ' + name + '\r\n')
        infofile.write(u'关注数: ' + str(num_gz[0]) + '\r\n')
        infofile.write(u'粉丝数: ' + str(num_fs[0]) + '\r\n')
        infofile.write(u'微博数: ' + str(num_wb[0]) + '\r\n')
        
        
    except Exception,e:      
        print "Error: ",e
    finally:    
        print u'VisitPersonPage!\n\n'
        print '**********************************************\n'
        infofile.write('=====================================================================\r\n\r\n')


#********************************************************************************
#                  第三步: 访问http://s.weibo.com/页面搜索热点信息
#                  爬取微博信息及评论,注意评论翻页的效果和微博的数量
#********************************************************************************    

def GetComment(key):
    try:
        global infofile       #全局文件变量
        driver.get("http://s.weibo.com/")
        print u'搜索热点主题:', key

        #输入主题并点击搜索
        item_inp = driver.find_element_by_xpath("//input[@class='searchInp_form']")
        item_inp.send_keys(key)
        item_inp.send_keys(Keys.RETURN)    #采用点击回车直接搜索

        #内容
        #content = driver.find_elements_by_xpath("//div[@class='content clearfix']/div/p")
        content = driver.find_elements_by_xpath("//p[@class='comment_txt']")
        print content
        i = 0
        print u'长度', len(content)
        while i<len(content):
            print '微博信息:'
            print content[i].text
            infofile.write(u'微博信息:\r\n')
            infofile.write(content[i].text + '\r\n')
            i = i + 1

        #评论 由于评论是动态加载,爬取失败
        #Error:  list index out of range
        comment = driver.find_elements_by_xpath("//p[@class='list_ul']/dl/dd/div[0]")
        j = 0
        while j<10:
            print comment[j].text
            j = j + 1


    except Exception,e:      
        print "Error: ",e
    finally:    
        print u'VisitPersonPage!\n\n'
        print '**********************************************\n'

             
#*******************************************************************************
#                                程序入口 预先调用
#         注意: 因为sina微博增加了验证码,但是你用Firefox登陆输入验证码
#         直接跳转到明星微博那部分,即: http://weibo.cn/guangxianliuyan
#*******************************************************************************
    
if __name__ == '__main__':

    #定义变量
    username = '1520161****'             #输入你的用户名
    password = '*********'               #输入你的密码

    #操作函数
    LoginWeibo(username, password)       #登陆微博

    #在if __name__ == '__main__':引用全局变量不需要定义 global inforead 省略即可
    print 'Read file:'
    user_id = inforead.readline()
    while user_id!="":
        user_id = user_id.rstrip('\r\n')
        print user_id
        VisitPersonPage(user_id)         #访问个人页面http://weibo.cn/guangxianliuyan
        user_id = inforead.readline()
        #break

    #搜索热点微博 爬取评论
    key = u'欢乐颂' 
    GetComment(key)
    
    infofile.close()
    inforead.close()
    

PS:后面是具体的实现过程分析讲解,如果你只需要代码,上面就是所有完整代码,但建议也看看后面的分析过程,虽然是傻瓜式爬虫,但至少能用,而且方法类似。



三. 登录入口


新浪微博登录常用接口: http://login.sina.com.cn/ 
对应主界面: http://weibo.com/
但是个人建议采用手机端微博入口: http://login.weibo.cn/login/  
对应主界面: http://weibo.cn/
通过比较下面两张图,分别是PC端和手机端,可以发现内容基本一致:



手机端下图所示,其中图片相对更小,同时内容更精简。






四. 分析-登录微博LoginWeibo


登录过程如下图所示,先通过函数获取用户名、密码、登录按钮结点,然后再自动输入信息并登录。如果需要输入验证码,也可以在手动输入。


对应源码:
#********************************************************************************
#                            第一步: 登陆weibo.cn 
#        该方法针对weibo.cn有效(明文形式传输数据) weibo.com见学弟设置POST和Header方法
#                LoginWeibo(username, password) 参数用户名 密码
#********************************************************************************

def LoginWeibo(username, password):
    try:
        #输入用户名/密码登录
        print u'准备登陆Weibo.cn网站...'
        driver.get("http://login.sina.com.cn/")
        elem_user = driver.find_element_by_name("username")
        elem_user.send_keys(username) #用户名
        elem_pwd = driver.find_element_by_name("password")
        elem_pwd.send_keys(password)  #密码
        #elem_rem = driver.find_element_by_name("safe_login")
        #elem_rem.click()             #安全登录

        #重点: 暂停时间输入验证码(http://login.weibo.cn/login/ 手机端需要)
        time.sleep(20)
        
        elem_sub = driver.find_element_by_xpath("//input[@class='smb_btn']")
        elem_sub.click()              #点击登陆 因无name属性
        time.sleep(2)
        
        #获取Coockie 推荐资料:http://www.cnblogs.com/fnng/p/3269450.html
        print driver.current_url
        print driver.get_cookies()  #获得cookie信息 dict存储
        print u'输出Cookie键值对信息:'
        for cookie in driver.get_cookies(): 
            #print cookie
            for key in cookie:
                print key, cookie[key]
                    
        #driver.get_cookies()类型list 仅包含一个元素cookie类型dict
        print u'登陆成功...'
        
        
    except Exception,e:      
        print "Error: ",e
    finally:    
        print u'End LoginWeibo!\n\n'

分析网页结点如下图所示:


核心代码:
        elem_user = driver.find_element_by_name("username")
        elem_user.send_keys(username)     #用户名
        elem_pwd = driver.find_element_by_name("password")
        elem_pwd.send_keys(password)      #密码
        elem_sub = driver.find_element_by_xpath("//input[@class='smb_btn']")
        elem_sub.click()                               #点击登陆

登录后跳转到下面页面:





五. 分析-爬取用户个人信息VisitPersonPage


通过URL+用户ID的形式访问信息,访问页面如下图所示:


代码如下所示:
#********************************************************************************
#                  第二步: 访问个人页面http://weibo.cn/5824697471并获取信息
#                                VisitPersonPage()
#        编码常见错误 UnicodeEncodeError: 'ascii' codec can't encode characters 
#********************************************************************************

def VisitPersonPage(user_id):

    try:
        global infofile       #全局文件变量
        url = "http://weibo.com/" + user_id
        driver.get(url)
        print u'准备访问个人网站.....', url
        print u'个人详细信息'
        
        #用户id
        print u'用户id: ' + user_id

        #昵称
        str_name = driver.find_element_by_xpath("//div[@class='pf_username']/h1")
        name = str_name.text        #str_name.text是unicode编码类型
        print u'昵称: ', name
        
        #关注数 粉丝数 微博数 <td class='S_line1'>
        str_elem = driver.find_elements_by_xpath("//table[@class='tb_counter']/tbody/tr/td/a")
        str_gz = str_elem[0].text    #关注数
        num_gz = re.findall(r'(\w*[0-9]+)\w*', str_gz)
        str_fs = str_elem[1].text    #粉丝数
        num_fs = re.findall(r'(\w*[0-9]+)\w*', str_fs)
        str_wb = str_elem[2].text    #微博数
        num_wb = re.findall(r'(\w*[0-9]+)\w*', str_wb)
        print u'关注数: ', num_gz[0]
        print u'粉丝数: ', num_fs[0]
        print u'微博数: ', num_wb[0]

        #文件操作写入信息
        infofile.write('=====================================================================\r\n')
        infofile.write(u'用户: ' + user_id + '\r\n')
        infofile.write(u'昵称: ' + name + '\r\n')
        infofile.write(u'关注数: ' + str(num_gz[0]) + '\r\n')
        infofile.write(u'粉丝数: ' + str(num_fs[0]) + '\r\n')
        infofile.write(u'微博数: ' + str(num_wb[0]) + '\r\n')
        
        
    except Exception,e:      
        print "Error: ",e
    finally:    
        print u'VisitPersonPage!\n\n'
        print '**********************************************\n'
        
其中SinaWeibo_List_best_1.txt中仅包含两个用户id的情况:


该部分输出如下图所示:


分析页面DOM树结构如下图所示:



同时这里只获取简单的信息,详细信息还可以自动点击"查看更多"进行获取:



六. 分析-爬取微博和评论信息GetComment


该部分代码如下:
#********************************************************************************
#                  第三步: 访问http://s.weibo.com/页面搜索热点信息
#                  爬取微博信息及评论,注意评论翻页的效果和微博的数量
#********************************************************************************    

def GetComment(key):
    try:
        global infofile       #全局文件变量
        driver.get("http://s.weibo.com/")
        print u'搜索热点主题:', key

        #输入主题并点击搜索
        item_inp = driver.find_element_by_xpath("//input[@class='searchInp_form']")
        item_inp.send_keys(key)
        item_inp.send_keys(Keys.RETURN)    #采用点击回车直接搜索

        #内容
        #content = driver.find_elements_by_xpath("//div[@class='content clearfix']/div/p")
        content = driver.find_elements_by_xpath("//p[@class='comment_txt']")
        print content
        i = 0
        print u'长度', len(content)
        while i<len(content):
            print '微博信息:'
            print content[i].text
            infofile.write(u'微博信息:\r\n')
            infofile.write(content[i].text + '\r\n')
            i = i + 1

        #评论 由于评论是动态加载,爬取失败
        #Error:  list index out of range
        comment = driver.find_elements_by_xpath("//p[@class='list_ul']/dl/dd/div[0]")
        j = 0
        while j<10:
            print comment[j].text
            j = j + 1


    except Exception,e:      
        print "Error: ",e
    finally:    
        print u'VisitPersonPage!\n\n'
        print '**********************************************\n'

        
通过访问该URL进行热点搜索: http://s.weibo.com/



再通过核定代码输入主题如“欢乐颂”并点击回车键,分析节点方法与前面类似:
        item_inp = driver.find_element_by_xpath("//input[@class='searchInp_form']")
        item_inp.send_keys(key)
        item_inp.send_keys(Keys.RETURN)    #采用点击回车直接搜索

自动返回搜索结果如下图所示:


分析DOM树结构如下,右键浏览器"审查元素":


分析具体的信息如下所示:


但爬取博客过程中,总显示空值,不知道为什么,怀疑是动态加载的。
content = driver.find_elements_by_xpath("//div[@class='content clearfix']/div/p")
content = driver.find_elements_by_xpath("//p[@class='comment_txt']")

评论信息需要点击"评论1897"才能进行加载:


对应源码如下所示,它是动态进行加载的:





如图,审查元素点击"评论"可以发现它是通过JavaScript加载,这就比较头疼了。



PS:最后希望文章对你有所帮助!其实方法很简单,希望你能理解这种思想,如何分析HTML源码及DOM树结构,然后动态获取自己需要的信息。
关于如何动态爬取评论部分我还在研究当中,实在不行可能只能通过手机端进行爬取了。同时因为最近太忙,只能写写这种效率很低的傻瓜式爬虫,后面毕业了会深入研究爬虫知识。但至少代码能运行,可以爬取信息,当前阶段就非常不错了。不喜勿喷,加油~

(By:Eastmount 2016-04-24 早上7点半   http://blog.csdn.net/eastmount/ )


作者:Eastmount 发表于2016/4/24 7:29:34 原文链接
阅读:5 评论:0 查看评论

相关 [python selenium 新浪微博] 推荐:

[Python爬虫] Selenium爬取新浪微博客户端用户信息、热点话题及评论 (上)

- - CSDN博客推荐文章
前一篇文章" [python爬虫] Selenium爬取新浪微博内容及用户信息"简单讲述了如何爬取新浪微博手机端用户信息和微博信息. 用户信息:包括用户ID、用户名、微博数、粉丝数、关注数等. 微博信息:包括转发或原创、点赞数、转发数、评论数、发布时间、微博内容等. 它主要通过从文本txt中读取用户id,通过"URL+用户ID" 访问个人网站,如柳岩:.

[python爬虫] Selenium常见元素定位方法和操作的学习介绍

- - CSDN博客编程语言推荐文章
        这篇文章主要Selenium+Python自动测试或爬虫中的常见定位方法、鼠标操作、键盘操作介绍,希望该篇基础性文章对你有所帮助,如果有错误或不足之处,请海涵~.         前文目录:.          [Python爬虫] 在Windows下安装PhantomJS和CasperJS及入门介绍(上).

Selenium Grid简介与安装

- - CSDN博客互联网推荐文章
      很多敏捷团队已经使用了Selenium和Watir等 工具进行验收测试或用户接口测试. 这些工具通过驱动Web浏览器的方式反映用户体验,并且为测试那些使用DHTML和Ajax构建的动态接口提供强力支 持. 然而,随着更多的团队采纳类似的工具,他们发现,运行这一整套浏览器驱动的Web接口测试会花费很长时间,而导致构建太慢.

围攻新浪微博

- Jos - 望月的博客
在国内的门户微博中,新浪微博无疑是目前用户数量最多、媒体属性最强的,但是,最近,却连续看到一些互联网的知名人士高调宣布退出或者关闭新浪微博的博文,使用和不使用某个产品本就是个人的自由,但如此高调的宣布,并进行口诛笔伐,就值得关注了. 本文试图通过分析谷奥事件,宋石男和贾葭两位老师离开新浪微博的事件分析新浪微博的是与非.

新浪微博连接 2.3

- leeking001 - 我爱水煮鱼
新浪微博连接是我使用新浪微博 API 接口开发的一个 WordPress 插件,它的主要功能是能让用户使用新浪微博账号登陆 WordPress 博客,并且可以直接使用新浪微博的头像,同步博客日志到 WordPress 博客. 经过几天的测试,新浪微博连接插件升级到 2.3,主要修正:同步博客到新浪微博的问题,并且同步内容更为丰富,规则改为:【日志标题】+ 日志内容摘要 + 日志链接.

新浪微博n大傻

- suki - broom&#39;s blog
看不到follow的人之间的交互这类产品本身的问题就不提了,就说说用户行为的傻. 其中有些行为也是产品本身纵容的. 三天两头换id的,搞个巨长的id既占字数又让别人压根没法手动@的,带个公司前缀的,用流行语的. 完全没有网络时代id就是个人身份的概念,意识还停留在QQ时代,以为随便改昵称呢. 某些专门发垃圾小段子的帐号尤甚.

新浪微博不是Twitter

- 马克叔叔 - 月光博客
  Twitter是互联网短信,新浪微博以微博客Twitter式弱关系切入,正在转型SNS. 转型的挑战在于:1.如何融合弱关系和强关系. 2.如何用弱关系倒逼中国社会的强关系和潜关系.   国内有一些Twitter的拥趸,认为微博抄Twitter都抄不到点子上.   “Twitter 是四两拨千斤的艺术.

V5后的新浪微博

- - It Talks--上海魏武挥的博客
正是在这个内外交困的时刻,新浪微博展开了它的商业化之旅,前途如何,尚未可知. 近日新浪微博发布了它的第五个版本,称为“V5”,在这个版本中,一个很明显的变化是:它长的有点像Facebook,用户不仅可以设置较大的头像,也可以在顶部自定义一张大图. V5版本的一些细节做得很用心,无论是提示语,还是版式的细微之处.

java模拟浏览器包htmlunit,selenium

- - BlogJava-首页技术区
发现一个很不错的模拟浏览器包htmlunit,它可以直接执行访问网站地址,并执行相应的JavaScript脚本;这个功能对于网站爬虫有很大的帮助,一些网站使用了ajax,如果使用简单的http访问只能抓到原始的html源码,但对于页面内执行的ajax却无法获取;使用这个包后,可以将执行ajax后的html源码一并抓取下来.

robotframework + selenium实现网站自动测试

- - idv2
本文参考: How to use RobotFramework with the Selenium Library. Selenium是个强大的自动化测试工具,可以手工编写或自动录制测试脚本,可以手工执行,也可以自动执行. 而 robotframework是个通用的自动化测试框架. robotframework-seleniumlibrary是robotframework的一个测试库,它可以集成Selenium,并提供一套简单易懂的语法用于书写测试用例(好处就是测试人员不用学任何编程语言也能写测试用例了).