Python selenium抓取微博内容

(一)编程环境

操作系统:Win 10
编程语言:Python 3.6

(二)安装selenium

这里使用selenium实现。
如果没有安装过python的selenium库,则安装命令如下

pip install selenium

(三)下载ChromeDriver

因为selenium要用到浏览器的驱动,这里我用的是Google Chrome浏览器,所以要先下载ChromeDriver.exe并放到C:\Program Files (x86)\Google\Chrome\Application\目录下。
注意,放到别的目录下也行,只要在代码里填上正确的路径即可。

Python selenium抓取微博内容_第1张图片

(四)登录微博

通常而言,m站的网页结构比pc站要简单的多,咱们可以从m站入手。微博m站登录界面的网址是 https://passport.weibo.cn/signin/login
在Chrome浏览器中打开此地址,并右键点击界面的任何位置–>查看网页源代码,发现邮箱/手机号框的id为loginName,密码输入框的id为loginPassword,登录按纽的id为loginAction。

from selenium import webdriver
import time

#全局变量
driver = webdriver.Chrome("C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe")


def loginWeibo(username, password):
    driver.get('https://passport.weibo.cn/signin/login')
    time.sleep(3)

    driver.find_element_by_id("loginName").send_keys(username)
    driver.find_element_by_id("loginPassword").send_keys(password)
    driver.find_element_by_id("loginAction").click()

    #driver.close()

执行后可以看到自动登录的过程及登录成功的界面

Python selenium抓取微博内容_第2张图片

(五)爬取微博内容

从微博爬取内容有两种方式:
(1)申请成为新浪开发者并调用微博API
(2)使用爬虫程序
因为微博API有好多限制,比如只能获取某用户的最近的10条微博内容,而不能获取全部历史微博内容。

这里咱们采用爬虫方式。
程序如下:

from selenium import webdriver
import time
import re

#全局变量
driver = webdriver.Chrome("C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe")


def loginWeibo(username, password):
    driver.get('https://passport.weibo.cn/signin/login')
    time.sleep(3)

    driver.find_element_by_id("loginName").send_keys(username)
    driver.find_element_by_id("loginPassword").send_keys(password)
    driver.find_element_by_id("loginAction").click()

    #这里只是看一下cookie内容,下面不会用到这个cookie值,因为driver会把cookie自动带过去
    cookies = driver.get_cookies()
    cookie_list = []
    for dict in cookies:
        cookie = dict['name'] + '=' + dict['value']
        cookie_list.append(cookie)
    cookie = ';'.join(cookie_list)
    print (cookie)

    #driver.close()


def visitUserInfo(userId):
    driver.get('http://weibo.cn/' + userId)

    print('********************')   
    print('用户资料')

    # 1.用户id
    print('用户id:' + userId)

    # 2.用户昵称
    strName = driver.find_element_by_xpath("//div[@class='ut']")
    strlist = strName.text.split(' ')
    nickname = strlist[0]
    print('昵称:' + nickname)

    # 3.微博数、粉丝数、关注数
    strCnt = driver.find_element_by_xpath("//div[@class='tip2']")
    pattern = r"\d+\.?\d*"      # 匹配数字,包含整数和小数
    cntArr = re.findall(pattern, strCnt.text)
    print(strCnt.text)
    print("微博数:" + str(cntArr[0]))
    print("关注数:" + str(cntArr[1]))
    print("粉丝数:" + str(cntArr[2]))

    print('\n********************')
    # 4.将用户信息写到文件里
    with open("userinfo.txt", "w", encoding = "gb18030") as file:
        file.write("用户ID:" + userId + '\r\n')
        file.write("昵称:" + nickname + '\r\n')
        file.write("微博数:" + str(cntArr[0]) + '\r\n')
        file.write("关注数:" + str(cntArr[1]) + '\r\n')
        file.write("粉丝数:" + str(cntArr[2]) + '\r\n')


def visitWeiboContent(userId):
    pageList = driver.find_element_by_xpath("//div[@class='pa']")
    print(pageList.text)
    pattern = r"\d+\d*"         # 匹配数字,只包含整数
    pageArr = re.findall(pattern, pageList.text)
    totalPages = pageArr[1]     # 总共有多少页微博
    print(totalPages)

    pageNum = 1                 # 第几页
    numInCurPage = 1            # 当前页的第几条微博内容
    curNum = 0                  # 全部微博中的第几条微博
    contentPath = "//div[@class='c'][{0}]"
    #while(pageNum <= 3):   
    while(pageNum <= int(totalPages)):
        try:
            contentUrl = "http://weibo.cn/" + userId + "?page=" + str(pageNum)
            driver.get(contentUrl)
            content = driver.find_element_by_xpath(contentPath.format(numInCurPage)).text
            #print("\n" + content)                  # 微博内容,包含原创和转发
            if "设置:皮肤.图片.条数.隐私" not in content:
                numInCurPage += 1
                curNum += 1
                with open("weibocontent.txt", "a", encoding = "gb18030") as file:
                    file.write(str(curNum) + '\r\n' + content + '\r\n\r\n') 
            else:
                pageNum += 1                        # 抓取新一页的内容
                numInCurPage = 1                    # 每一页都是从第1条开始抓
                time.sleep(20)                      # 要隔20秒,否则会被封
        except exception as e:
            print("curNum:" + curNum)
            print(e)
        finally:
            pass
    print("Load weibo content finished!")       


if __name__ == '__main__':
    username = '******'             # 输入微博账号
    password = '******'             # 输入密码
    loginWeibo(username, password)      # 要先登录,否则抓取不了微博内容

    time.sleep(3)
    uid = 'xywyw'                       # “寻医问药”的个性域名
    visitUserInfo(uid)                  # 获取用户基本信息
    visitWeiboContent(uid)              # 获取微博内容

运行结果:
生成了两个文件
1)userinfo.txt,用来存放用户的基本资料

Python selenium抓取微博内容_第3张图片

2)weiboconten.txt用来存放该用户的所有历史微博内容

Python selenium抓取微博内容_第4张图片

注意,程序里每爬一页,都需要睡眠20秒。这样可以防止被封,被封会提示HTTP错误403

Python selenium抓取微博内容_第5张图片

猜测新浪是根据cookie来封的,不是根据用户名和IP。因为403页面出现进,把浏览器的cookie清空,webo.cn就可以立即访问。如果不清空的话,等半个小时左右,也可以继续访问。
这里20秒是多次试验得到的经验值。若改成10秒,爬取200多条后会出现403错误;若改成15秒,爬取500多条后会出现403错误。


TopCoder & Codeforces & AtCoder交流QQ群:648202993
更多内容请关注微信公众号
wechat_public_header.jpg

你可能感兴趣的:(Python)