IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> selenium爬取微博(移动端)评论 -> 正文阅读

[开发测试]selenium爬取微博(移动端)评论

今天我们进行的是微博移动端的评论爬取,将爬取的数据存放到excel表格中,这本来使件很容易的事情,结果我看很多博主都没有做,所以今天我们就来做一下吧。

这是我们今天要爬取的微博,人民日报每天都有几十条的微博输出,完全可以满足我们的要求,由于我们是使用的selenium框架爬取的微博评论,selenium最大的缺点就是出奇的慢,当然,selenium也有自己的优点,那就是所见其所得,操作简单,易上手。

我们知道微博的反爬能力还是很强的,他们有自己的一个反爬团队,所以我建议新手不要去尝试爬取网页端,先从容易的移动端做起就很好了。

接下来我们介绍爬取思路

要想爬取微博移动端的第一步就是先登录上去,那怎么解决这个登录问题呢?

?

登录手机微博可以通过输入手机号,获取验证码登录,或者通过用账号密码登录,但是他们在各自发送几次验证码之后就会提示今天的次数已经达到上限,所以我们不可能每次都要通过,输入验证码的形式登录。这时,cookies可以为我们解决登录问题。

cookies是什么?

cookies是发送第一次请求的时候,将共享数据发送到浏览器中进行保存,以后每次请求都会将共享数据发送到服务器,这也是为什么我们用浏览器可以直接登录的原因。

cookies虽好,但是具有一定的时效性,一段时间后可能就不能使用了,所以我们就要更换cookies。

如何获取cookeis?

获取cookies代码段

from selenium.webdriver import Firefox
import time


if __name__=='__main__':
    web=Firefox()
    #打开网址
    web.get('https://m.weibo.cn/login?backURL=https%3A%2F%2Fm.weibo.cn%2F')
    time.sleep(5)
    #输入手机号
    web.find_element_by_xpath('/html/body/div/div[1]/div/div/form/div/input').send_keys('你的手机号')
    time.sleep(2)
    #点击获取验证码
    web.find_element_by_xpath('/html/body/div/div[1]/div/div/a').click()
    time.sleep(30)
    #这里要手动点击验证,输入验证码

    cookie=web.get_cookies()
    time.sleep(3)
    print(cookie)

?获取到的cookie

之后我们就可以拿着cookies去登录了。

登录代码段

from selenium.webdriver import Firefox
import time

if __name__=='__main__':
    web=Firefox()
    #目标网址
    web.get('https://m.weibo.cn/?sudaref=m.weibo.cn&display=0&retcode=6102')
    time.sleep(1)
    cookies ={'name': '_T_WM', 'value': '65791748215', 'path': '/', 'domain': '.weibo.cn', 'secure': False, 'httpOnly': False, 'expiry': 1630771201, 'sameSite': 'None'}, {'name': 'WEIBOCN_FROM', 'value': '1110006030', 'path': '/', 'domain': '.weibo.cn', 'secure': False, 'httpOnly': True, 'sameSite': 'None'}, {'name': 'SUB', 'value': '_2A25MN01wDeRhGeFL7VYQ9izIzDqIHXVv2FM4rDV6PUJbktCOLVXbkW1Nfc54NlnhyBWsRdhGK0hSNZNSrxkxgB2b', 'path': '/', 'domain': '.weibo.cn', 'secure': True, 'httpOnly': True, 'expiry': 1662283936, 'sameSite': 'None'}, {'name': 'SUBP', 'value': '0033WrSXqPxfM725Ws9jqgMF55529P9D9W5XQQxV.jJsdH2hb0UBBfNY5NHD95QNSKqXeKqEShMcWs4DqcjMi--NiK.Xi-2Ri--ciKnRi-zNS0-cSh2ceoBNSntt', 'path': '/', 'domain': '.weibo.cn', 'secure': True, 'httpOnly': False, 'expiry': 1662283936, 'sameSite': 'None'}, {'name': 'SSOLoginState', 'value': '1630747937', 'path': '/', 'domain': '.weibo.cn', 'secure': True, 'httpOnly': False, 'sameSite': 'None'}, {'name': 'XSRF-TOKEN', 'value': 'fb173e', 'path': '/', 'domain': '.m.weibo.cn', 'secure': False, 'httpOnly': False, 'expiry': 1630749197, 'sameSite': 'None'}, {'name': 'MLOGIN', 'value': '1', 'path': '/', 'domain': '.weibo.cn', 'secure': False, 'httpOnly': False, 'expiry': 1630751597, 'sameSite': 'None'}, {'name': 'M_WEIBOCN_PARAMS', 'value': 'lfid%3D102803%26luicode%3D20000174', 'path': '/', 'domain': '.weibo.cn', 'secure': False, 'httpOnly': True, 'expiry': 1630748597, 'sameSite': 'None'}
    for cookie in cookies:
        web.add_cookie(cookie)
    time.sleep(1)
    #一定要记得刷新
    web.refresh()

?

将数据存放到excel表格代码段

excel_path = "D:\\移动"  # 写入的excel文件路径
now_time = strftime("%Y-%m-%d-%H")  # 获取时间戳为excel文件名和表名


# 创建excel追加数据到表中
class Write_Excel():
    def __init__(self):
        self.path = excel_path
        self.name = now_time + ".xls"
        self.filename = join(self.path, self.name)

    # 设置表格样式
    def set_style(self, name, height, bold=False):
        style = xlwt.XFStyle()
        font = xlwt.Font()
        font.name = name
        font.bold = bold
        font.color_index = 4
        font.height = height
        style.font = font
        return style

    # 新建excel文件
    def new_excel(self):
        f = xlwt.Workbook()
        f.add_sheet(now_time, cell_overwrite_ok=True)  # 新增excel中表now_time
        f.save(self.filename)
        print("文件【%s】创建成功" % self.name)

    # 对excel文件写入数据
    def add_to_excel(self, values):
        try:
            workbook = xlrd.open_workbook(self.filename)  # excel文件存在则直接打开
        except FileNotFoundError:  # excel文件不存在则先创建在打开
            self.new_excel()
            workbook = xlrd.open_workbook(self.filename)
        sheets = workbook.sheet_names()  # 获取工作簿中的所有表格
        worksheet = workbook.sheet_by_name(sheets[0])  # 获取工作簿中所有表格中的的第一个表格
        rows_old = worksheet.nrows  # 获取表格中已存在的数据的行数
        if rows_old == 0:  # 跳过首行写入,留存为标题行
            rows_old = 1
        new_workbook = copy(workbook)  # 将xlrd对象拷贝转化为xlwt对象,旧数据复制保存
        new_worksheet = new_workbook.get_sheet(0)  # 获取转化后工作簿中的第一个表格
        i = 0
        for value in values:
            new_worksheet.write(rows_old, i, value)  # 追加写入数据,从rows_old行开始写入
            i += 1
        print(" 文件【{0}】表【{1}】第【{2}】行追加数据{3}".format(self.name, now_time, rows_old, values))
        # 定义标题行信息
        title_row = ["名称", "位置", "申请者", "时间", " ", " ", " "]
        for n in range(0, len(title_row)):
            new_worksheet.write(0, n, title_row[n], self.set_style('Times New Roman', 220, True))
        new_workbook.save(self.filename)  # 保存excel文件

爬取数据代码段

from os.path import join
from time import strftime
import xlrd
import xlwt
from xlutils.copy import copy
from selenium.webdriver import Firefox
import time
from selenium.webdriver.common.action_chains import ActionChains
import driver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import emoji
from re import sub
import emoji
import re
from selenium import webdriver
from selenium.webdriver.common.keys import Keys




excel_path = "D:\\移动"  # 写入的excel文件路径
now_time = strftime("%Y-%m-%d-%H")  # 获取时间戳为excel文件名和表名


# 创建excel追加数据到表中
class Write_Excel():
    def __init__(self):
        self.path = excel_path
        self.name = now_time + ".xls"
        self.filename = join(self.path, self.name)

    # 设置表格样式
    def set_style(self, name, height, bold=False):
        style = xlwt.XFStyle()
        font = xlwt.Font()
        font.name = name
        font.bold = bold
        font.color_index = 4
        font.height = height
        style.font = font
        return style

    # 新建excel文件
    def new_excel(self):
        f = xlwt.Workbook()
        f.add_sheet(now_time, cell_overwrite_ok=True)  # 新增excel中表now_time
        f.save(self.filename)
        print("文件【%s】创建成功" % self.name)

    # 对excel文件写入数据
    def add_to_excel(self, values):
        try:
            workbook = xlrd.open_workbook(self.filename)  # excel文件存在则直接打开
        except FileNotFoundError:  # excel文件不存在则先创建在打开
            self.new_excel()
            workbook = xlrd.open_workbook(self.filename)
        sheets = workbook.sheet_names()  # 获取工作簿中的所有表格
        worksheet = workbook.sheet_by_name(sheets[0])  # 获取工作簿中所有表格中的的第一个表格
        rows_old = worksheet.nrows  # 获取表格中已存在的数据的行数
        if rows_old == 0:  # 跳过首行写入,留存为标题行
            rows_old = 1
        new_workbook = copy(workbook)  # 将xlrd对象拷贝转化为xlwt对象,旧数据复制保存
        new_worksheet = new_workbook.get_sheet(0)  # 获取转化后工作簿中的第一个表格
        i = 0
        for value in values:
            new_worksheet.write(rows_old, i, value)  # 追加写入数据,从rows_old行开始写入
            i += 1
        print(" 文件【{0}】表【{1}】第【{2}】行追加数据{3}".format(self.name, now_time, rows_old, values))
        # 定义标题行信息
        title_row = ["名称", "位置", "申请者", "时间", " ", " ", " "]
        for n in range(0, len(title_row)):
            new_worksheet.write(0, n, title_row[n], self.set_style('Times New Roman', 220, True))
        new_workbook.save(self.filename)  # 保存excel文件

if __name__ == "__main__":

    # 模拟浏览器
    user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0'
    opt = webdriver.FirefoxOptions()
    opt.add_argument('--user-agent=%s' % user_agent)
    web = webdriver.Firefox(executable_path='D:\\软件\\firefox\\geckodriver.exe', options=opt)
    # 打开微博移动端

    print('打开微博移动端')
    web.get('https://m.weibo.cn/u/2803301701?uid=2803301701&t=0&luicode=10000011&lfid=100103type%3D1%26q%3D%E4%BA%BA%E6%B0%91%E6%97%A5%E6%8A%A5')
    time.sleep(1)
    cookies ={'name': '_T_WM', 'value': '65791748215', 'path': '/', 'domain': '.weibo.cn', 'secure': False, 'httpOnly': False, 'expiry': 1630771201, 'sameSite': 'None'}, {'name': 'WEIBOCN_FROM', 'value': '1110006030', 'path': '/', 'domain': '.weibo.cn', 'secure': False, 'httpOnly': True, 'sameSite': 'None'}, {'name': 'SUB', 'value': '_2A25MN01wDeRhGeFL7VYQ9izIzDqIHXVv2FM4rDV6PUJbktCOLVXbkW1Nfc54NlnhyBWsRdhGK0hSNZNSrxkxgB2b', 'path': '/', 'domain': '.weibo.cn', 'secure': True, 'httpOnly': True, 'expiry': 1662283936, 'sameSite': 'None'}, {'name': 'SUBP', 'value': '0033WrSXqPxfM725Ws9jqgMF55529P9D9W5XQQxV.jJsdH2hb0UBBfNY5NHD95QNSKqXeKqEShMcWs4DqcjMi--NiK.Xi-2Ri--ciKnRi-zNS0-cSh2ceoBNSntt', 'path': '/', 'domain': '.weibo.cn', 'secure': True, 'httpOnly': False, 'expiry': 1662283936, 'sameSite': 'None'}, {'name': 'SSOLoginState', 'value': '1630747937', 'path': '/', 'domain': '.weibo.cn', 'secure': True, 'httpOnly': False, 'sameSite': 'None'}, {'name': 'XSRF-TOKEN', 'value': 'fb173e', 'path': '/', 'domain': '.m.weibo.cn', 'secure': False, 'httpOnly': False, 'expiry': 1630749197, 'sameSite': 'None'}, {'name': 'MLOGIN', 'value': '1', 'path': '/', 'domain': '.weibo.cn', 'secure': False, 'httpOnly': False, 'expiry': 1630751597, 'sameSite': 'None'}, {'name': 'M_WEIBOCN_PARAMS', 'value': 'lfid%3D102803%26luicode%3D20000174', 'path': '/', 'domain': '.weibo.cn', 'secure': False, 'httpOnly': True, 'expiry': 1630748597, 'sameSite': 'None'}
    for cookie in cookies:
        web.add_cookie(cookie)
    web.refresh()
    time.sleep(10)

    # 爬取微博评论
    print('爬取微博评论')
    var2=0
    for i in range(4, 200000):
        number1=int(i/10)
        str1 = '/html/body/div/div[1]/div[1]/div[{}]/div/div/div/footer/div[2]/h4'.format(i)
        try:
             number_comment = web.find_element_by_xpath(str1).text
        except:
            print('没有对应微博')
            continue
        #var1_1判断是否带万
        if number_comment == '评论':
            print('无评论内容')
            continue
        var1_1=0
        for k in range(1,len(number_comment)):
            if number_comment[k]=='万':
                var1_1=1
                number_comments=10000
        if var1_1==0:
            number_comments=int(number_comment)
        if number_comments <= 20:
            print('评论数小于20')
            continue
        else:
            for w in range(3):
                # 第一个参数x是横向距离,第二个参数y是纵向距离
                js = 'window.scrollBy(0, 600)'  # 90表示滚动条下滑的长度(位置)
                web.execute_script(js)
                time.sleep(2)
            # 点击进入微博评论
            print('进入', i, '微博评论')
            ele = web.find_element_by_xpath(str1)
            web.execute_script('arguments[0].click()', ele)
            time.sleep(4)
            status = True
            var1 = 0
            time.sleep(3)
            while status:
                # 获取页面当前高度
                js = "return action=document.body.scrollHeight"
                height_1 = web.execute_script(js)
                # 将滚动条调整至页面底部
                time.sleep(2)
                print('将滚动条调整至页面底部')
                web.execute_script('window.scrollTo(0, document.body.scrollHeight)')
                time.sleep(3)
                # 获取页面现在的高度
                js2 = "return action=document.body.scrollHeight"
                height_2 = web.execute_script(js2)
                time.sleep(1)
                if height_1 == height_2 or var1 == 18:
                    # 跳出循环
                    status = False
                else:
                    var1 = var1 + 1
            # 爬取微博评论
            print('爬取微博评论')
            number_comments_2 = int(number_comments / 5)
            for j in range(1, number_comments_2):
                # 用户名
                str2 = '/html/body/div/div[1]/div/div[4]/div[2]/div[{}]/div/div/div/div/div[2]/div[1]/div/div/h4'.format(j)
                # 评论
                str3 = '/html/body/div/div[1]/div/div[4]/div[2]/div[{}]/div/div/div/div/div[2]/div[1]/div/div/h3'.format(j)
                try:
                    weibo_name = web.find_element_by_xpath(str2).text
                    weibo_comment = web.find_element_by_xpath(str3).text
                except:
                    break
                weibo_comment_end = re.sub('[a-zA-Z]', '', weibo_comment)

                # 判断微博评论是否符合要求
                if len(weibo_comment_end) >= 20:
                    weibo_sum = [weibo_name, weibo_comment_end]
                    # 输出结果
                    print(weibo_name, weibo_comment_end)
                    try:
                         Write_Excel().add_to_excel(values=weibo_sum)
                    except:
                        time.sleep(2)
                        continue
                else:
                    print('长度不符合要求')
        # 退出微博
        time.sleep(3)
        web.back()
        time.sleep(2)
        for w in range(3):
            # 第一个参数x是横向距离,第二个参数y是纵向距离
            js = 'window.scrollBy(0, 600)'  # 90表示滚动条下滑的长度(位置)
            web.execute_script(js)
            time.sleep(2)






  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-09-09 12:04:57  更:2021-09-09 12:06:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 0:28:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码