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

一. 文章介绍

前一篇文章"[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/ )

时间: 2024-12-14 18:54:34

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

[Python爬虫] Selenium爬取新浪微博移动端热点话题及评论 (下)

这篇文章主要讲述了使用python+selenium爬取新浪微博的热点话题和评论信息.其中使用该爬虫的缺点是效率极低,傻瓜式的爬虫,不能并行执行等,但是它的优点是采用分析DOM树结构分析网页源码并进行信息爬取,同时它可以通过浏览器进行爬取中间过程的演示及验证码的输入.这篇文章对爬虫的详细过程就不再论述了,主要是提供可运行的代码和运行截图即可.希望文章对你有所帮助吧~ 参考文章 [python爬虫] Selenium爬取新浪微博内容及用户信息 [Python爬虫] Selenium爬取新浪微博客户

[python爬虫] Selenium爬取CSDN博客摘要及问题

本文主要是采用Selenium来爬取CSDN的博文摘要,为后面对CSDN的热点技术.近几年专家发表的博客作数据分析.由于采用BeautifulSoup爬取该网站会报错"HTTPError: Forbidden",所以作者采用Selenium爬取.同时,在爬取过程中遇到了局部动态更新的问题,无法定位换页的问题,作者采用Firebug进行分析,也希望读者提出更好的方法.代码下载地址: 一. CSDN博客网站分析及问题 本文主要爬取CSDN专家的博客,因为专家的论文水平相对高点,同时专栏较多

[python爬虫] Selenium爬取内容并存储至MySQL数据库

前面我通过一篇文章讲述了如何爬取CSDN的博客摘要等信息.通常,在使用Selenium爬虫爬取数据后,需要存储在TXT文本中,但是这是很难进行数据处理和数据分析的.这篇文章主要讲述通过Selenium爬取我的个人博客信息,然后存储在数据库MySQL中,以便对数据进行分析,比如分析哪个时间段发表的博客多.结合WordCloud分析文章的主题.文章阅读量排名等.        这是一篇基础性的文章,希望对您有所帮助,如果文章中出现错误或不足之处,还请海涵.下一篇文章会简单讲解数据分析的过程. 一.

Python爬虫项目--爬取自如网房源信息

本次爬取自如网房源信息所用到的知识点: 1. requests get请求 2. lxml解析html 3. Xpath 4. MongoDB存储 正文 1.分析目标站点 1. url: http://hz.ziroom.com/z/nl/z3.html?p=2 的p参数控制分页 2. get请求 2.获取单页源码 1 # -*- coding: utf-8 -*- 2 import requests 3 import time 4 from requests.exceptions import

21天打造分布式爬虫-Selenium爬取拉钩职位信息(六)

6.1.爬取第一页的职位信息 第一页职位信息 from selenium import webdriver from lxml import etree import re import time class LagouSpider(object): def __init__(self): self.driver = webdriver.Chrome() #python职位 self.url = 'https://www.lagou.com/jobs/list_python?labelWords

Python爬虫入门 | 爬取豆瓣电影信息

这是一个适用于小白的Python爬虫免费教学课程,只有7节,让零基础的你初步了解爬虫,跟着课程内容能自己爬取资源.看着文章,打开电脑动手实践,平均45分钟就能学完一节,如果你愿意,今天内你就可以迈入爬虫的大门啦~好啦,正式开始我们的第二节课<爬取豆瓣电影信息>吧!啦啦哩啦啦,都看黑板~1. 爬虫原理1.1 爬虫基本原理听了那么多的爬虫,到底什么是爬虫?爬虫又是如何工作的呢?我们先从"爬虫原理"说起.爬虫又称为网页蜘蛛,是一种程序或脚本.但重点在于:它能够按照一定的规则,自动

利用Selenium爬取淘宝商品信息

一.  Selenium和PhantomJS介绍 Selenium是一个用于Web应用程序测试的工具,Selenium直接运行在浏览器中,就像真正的用户在操作一样.由于这个性质,Selenium也是一个强大的网络数据采集工具,其可以让浏览器自动加载页面,这样,使用了异步加载技术的网页,也可获取其需要的数据. Selenium模块是Python的第三方库,可以通过pip进行安装: pip3 install selenium Selenium自己不带浏览器,需要配合第三方浏览器来使用.通过help命

基于webmagic的爬虫小应用--爬取知乎用户信息

听到“爬虫”,是不是第一时间想到Python/php ? 多少想玩爬虫的Java学习者就因为语言不通而止步.Java是真的不能做爬虫吗? 当然不是. 只不过python的3行代码能解决的问题,而Java要30行. 这里推荐大家一个大牛做的java爬虫框架 [WebMagic] 文档简单易懂!java爬虫开发的福利啊! 一起来动手做一个小应用吧! 爬虫小应用–知乎用户信息 爬虫思想有3步 1. 抽取目标链接 2. 抽取需要的信息 3. 处理数据 一. 抽取目标链接 (确定入口地址,这里的入口是ht

Python爬虫之爬取煎蛋网妹子图

这篇文章通过简单的Python爬虫(未使用框架,仅供娱乐)获取并下载煎蛋网妹子图指定页面或全部图片,并将图片下载到磁盘. 首先导入模块:urllib.request.re.os import urllib.request import re import os urllib.request模块用于获取HTML页面数据 re模块用于通过正则表达式解析并截取HTML页面图片url os模块用于文件夹相关操作 代码不多,直接贴出来,代码解释在注释中: def crawl_jiandan(page, p