使用Selenium实现微博爬虫(预登录、展开全文、翻页)


Posted in Python onApril 13, 2021

前言

在CSDN发的第一篇文章,时隔两年,终于实现了爬微博的自由!本文可以解决微博预登录、识别“展开全文”并爬取完整数据、翻页设置等问题。由于刚接触爬虫,有部分术语可能用的不正确,请大家多指正!

一、区分动态爬虫和静态爬虫

1、静态网页
静态网页是纯粹的HTML,没有后台数据库,不含程序,不可交互,体量较少,加载速度快。静态网页的爬取只需四个步骤:发送请求、获取相应内容、解析内容及保存数据。

2、动态网页
动态网页上的数据会随时间及用户交互发生变化,因此数据不会直接呈现在网页源代码中,数据将以Json的形式保存起来。因此,动态网页比静态网页多了一步,即需渲染获得相关数据。

3、区分动静态网页的方法
加载网页后,点击右键,选中“查看网页源代码”,如果网页上的绝大多数字段都出现源代码中,那么这就是静态网页,否则是动态网页。

使用Selenium实现微博爬虫(预登录、展开全文、翻页)

二、动态爬虫的两种方法

1.逆向分析爬取动态网页
适用于调度资源所对应网址的数据为json格式,Javascript的触发调度。主要步骤是获取需要调度资源所对应的网址-访问网址获得该资源的数据。(此处不详细讲解)

2.使用Selenium库爬取动态网页
使用Selenium库,该库使用JavaScript模拟真实用户对浏览器进行操作。本案例将使用该方法。

三、安装Selenium库及下载浏览器补丁

1.Selenium库使用pip工具进行安装即可。
2.下载与Chrome浏览器版本匹配的浏览器补丁。
Step1:查看Chrome的版本

使用Selenium实现微博爬虫(预登录、展开全文、翻页)

Step2:去下载相应版本的浏览器补丁。网址:http://npm.taobao.org/mirrors/chromedriver/
Step3:解压文件,并将之放到与python.exe同一文件下

使用Selenium实现微博爬虫(预登录、展开全文、翻页)

四、页面打开及预登录

1.导入selenium包

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import time
import pandas as pd

2.打开页面

driver = webdriver.Chrome()    
print('准备登陆Weibo.cn网站...')
#发送请求
driver.get("https://login.sina.com.cn/signup/signin.php")
wait = WebDriverWait(driver,5)
#重要:暂停1分钟进行预登陆,此处填写账号密码及验证
time.sleep(60)

3.采用交互式运行,运行完上面两段程序,会弹出一个框,这个框就是用来模拟网页的交互。在这个框中完成登录(包括填写登录名、密码及短信验证等)

使用Selenium实现微博爬虫(预登录、展开全文、翻页)

4.完成预登录,则进入个人主页

使用Selenium实现微博爬虫(预登录、展开全文、翻页)

五、关键词搜索操作

1.定位上图中的关键词输入框,并在框中输入搜索对象,如“努力学习”

#使用selector去定位关键词搜索框
s_input = driver.find_element_by_css_selector('#search_input')
#向搜索框中传入字段
s_input.send_keys("努力学习")
#定位搜索键
confirm_btn = driver.find_element_by_css_selector('#search_submit')
#点击
confirm_btn.click()

2.当完成上步的代码运行后,会弹出新的窗口,从个人主页跳到微博搜索页。但是driver仍在个人主页,需要人为进行driver的移动,将之移动到微博搜索页。

使用Selenium实现微博爬虫(预登录、展开全文、翻页)

3.使用switch_to.window()方法移位

#人为移动driver
driver.switch_to.window(driver.window_handles[1])

六、识别“展开全文”并爬取数据

1.了解每个元素的Selector,用以定位(重点在于唯一标识性)

使用Selenium实现微博爬虫(预登录、展开全文、翻页)

2.使用Selector定位元素,并获取相应的数据

comment = []
username = []

#抓取节点:每个评论为一个节点(包括用户信息、评论、日期等信息),如果一页有20条评论,那么nodes的长度就为20
nodes = driver.find_elements_by_css_selector('div.card > div.card-feed > div.content')

#对每个节点进行循环操作
for i in range(0,len(nodes),1):
    #判断每个节点是否有“展开全文”的链接
    flag = False
    try:
        nodes[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").is_displayed()
        flag = True  
    except:
        flag = False
    
    #如果该节点具有“展开全文”的链接,且该链接中的文字是“展开全文c”,那么点击这个要素,并获取指定位置的文本;否则直接获取文本
    #(两个条件需要同时满足,因为该selector不仅标识了展开全文,还标识了其他元素,没有做到唯一定位)
    if(flag and nodes[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").text.startswith('展开全文c')):
        nodes[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").click()
        comment.append(nodes[i].find_element_by_css_selector('p[node-type="feed_list_content_full"]').text)
    else:
        comment.append(nodes[i].find_element_by_css_selector('p[node-type="feed_list_content"]').text)
    username.append(nodes[i].find_element_by_css_selector("div.info>div:nth-child(2)>a").text)

七、设置翻页

1.使用for循环实现翻页,重点在于识别“下一页”按钮,并点击它

for page in range(49):
    print(page)
    # 定位下一页按钮
    nextpage_button = driver.find_element_by_link_text('下一页')
    #点击按键
    driver.execute_script("arguments[0].click();", nextpage_button)
    wait = WebDriverWait(driver,5)
    #与前面类似
    nodes1 = driver.find_elements_by_css_selector('div.card > div.card-feed > div.content')
    for i in range(0,len(nodes1),1):
        flag = False
        try:
            nodes1[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").is_displayed()
            flag = True
        
        except:
            flag = False
        if (flag and nodes1[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").text.startswith('展开全文c')):
            nodes1[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").click()
            comment.append(nodes1[i].find_element_by_css_selector('p[node-type="feed_list_content_full"]').text)
        else:
            comment.append(nodes1[i].find_element_by_css_selector('p[node-type="feed_list_content"]').text)
        username.append(nodes1[i].find_element_by_css_selector("div.info>div:nth-child(2)>a").text)

八、保存数据

1.使用DataFrame保存字段

data = pd.DataFrame({'username':username,'comment':comment})

使用Selenium实现微博爬虫(预登录、展开全文、翻页)

2.导出到Excel

data.to_excel("weibo.xlsx")

九、完整代码

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
import time
import pandas as pd

'''打开网址,预登陆'''
driver = webdriver.Chrome()    
print('准备登陆Weibo.cn网站...')
#发送请求
driver.get("https://login.sina.com.cn/signup/signin.php")
wait = WebDriverWait(driver,5)
#重要:暂停1分钟进行预登陆,此处填写账号密码及验证
time.sleep(60)

'''输入关键词到搜索框,完成搜索'''
#使用selector去定位关键词搜索框
s_input = driver.find_element_by_css_selector('#search_input')
#向搜索框中传入字段
s_input.send_keys("努力学习")
#定位搜索键
confirm_btn = driver.find_element_by_css_selector('#search_submit')
#点击
confirm_btn.click()

#人为移动driver
driver.switch_to.window(driver.window_handles[1])

'''爬取第一页数据'''
comment = []
username = []

#抓取节点:每个评论为一个节点(包括用户信息、评论、日期等信息),如果一页有20条评论,那么nodes的长度就为20
nodes = driver.find_elements_by_css_selector('div.card > div.card-feed > div.content')

#对每个节点进行循环操作
for i in range(0,len(nodes),1):
    #判断每个节点是否有“展开全文”的链接
    flag = False
    try:
        nodes[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").is_displayed()
        flag = True  
    except:
        flag = False
    
    #如果该节点具有“展开全文”的链接,且该链接中的文字是“展开全文c”,那么点击这个要素,并获取指定位置的文本;否则直接获取文本
    #(两个条件需要同时满足,因为该selector不仅标识了展开全文,还标识了其他元素,没有做到唯一定位)
    if(flag and nodes[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").text.startswith('展开全文c')):
        nodes[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").click()
        comment.append(nodes[i].find_element_by_css_selector('p[node-type="feed_list_content_full"]').text)
    else:
        comment.append(nodes[i].find_element_by_css_selector('p[node-type="feed_list_content"]').text)
    username.append(nodes[i].find_element_by_css_selector("div.info>div:nth-child(2)>a").text)

'''循环操作,获取剩余页数的数据'''
for page in range(49):
    print(page)
    # 定位下一页按钮
    nextpage_button = driver.find_element_by_link_text('下一页')
    #点击按键
    driver.execute_script("arguments[0].click();", nextpage_button)
    wait = WebDriverWait(driver,5)
    #与前面类似
    nodes1 = driver.find_elements_by_css_selector('div.card > div.card-feed > div.content')
    for i in range(0,len(nodes1),1):
        flag = False
        try:
            nodes1[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").is_displayed()
            flag = True
        
        except:
            flag = False
        if (flag and nodes1[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").text.startswith('展开全文c')):
            nodes1[i].find_element_by_css_selector("p>a[action-type='fl_unfold']").click()
            comment.append(nodes1[i].find_element_by_css_selector('p[node-type="feed_list_content_full"]').text)
        else:
            comment.append(nodes1[i].find_element_by_css_selector('p[node-type="feed_list_content"]').text)
        username.append(nodes1[i].find_element_by_css_selector("div.info>div:nth-child(2)>a").text)

'''保存数据'''
data = pd.DataFrame({'username':username,'comment':comment})
data.to_excel("weibo.xlsx")

到此这篇关于使用Selenium实现微博爬虫(预登录、展开全文、翻页)的文章就介绍到这了,更多相关Selenium 微博爬虫 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python清除字符串里非字母字符的方法
Jul 02 Python
在Pycharm中项目解释器与环境变量的设置方法
Oct 29 Python
Python判断一个list中是否包含另一个list全部元素的方法分析
Dec 24 Python
Python设计模式之迭代器模式原理与用法实例分析
Jan 10 Python
如何爬取通过ajax加载数据的网站
Aug 15 Python
详解Django-channels 实现WebSocket实例
Aug 22 Python
Python devel安装失败问题解决方案
Jun 09 Python
基于Tensorflow的MNIST手写数字识别分类
Jun 17 Python
详解Anaconda 的安装教程
Sep 23 Python
基于python获取本地时间并转换时间戳和日期格式
Oct 27 Python
python 实现"神经衰弱"翻牌游戏
Nov 09 Python
python实现层次聚类的方法
Nov 01 Python
python用字节处理文件实例讲解
Apr 13 #Python
Python中相见恨晚的技巧
Apr 13 #Python
利用python做表格数据处理
python glom模块的使用简介
Apr 13 #Python
Python的flask接收前台的ajax的post数据和get数据的方法
Python使用sql语句对mysql数据库多条件模糊查询的思路详解
python实现简单反弹球游戏
You might like
分享一段PHP制作的中文拼音首字母工具类
2014/12/11 PHP
又十个超级有用的PHP代码片段
2015/09/24 PHP
jQuery侧边栏随窗口滚动实现方法
2013/03/04 Javascript
JQuery入门基础小实例(1)
2015/09/17 Javascript
jquery获取img的src值的简单实例
2016/05/17 Javascript
jQuery简单实现点击文本框复制内容到剪贴板上的方法
2016/08/01 Javascript
轻松掌握JavaScript策略模式
2016/08/25 Javascript
webuploader模态框ueditor显示问题解决方法
2016/12/27 Javascript
vue-router:嵌套路由的使用方法
2017/02/21 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图的组合双轴图效果示例【附demo源码下载】
2017/03/09 Javascript
Vue2.0基于vue-cli+webpack父子组件通信(实例讲解)
2017/09/14 Javascript
JS打印彩色菱形的实例代码
2018/08/15 Javascript
elementUI Vue 单个按钮显示和隐藏的变换功能(两种方法)
2018/09/04 Javascript
vue中的router-view组件的使用教程
2018/10/23 Javascript
使用post方法实现json往返传输数据的方法
2019/03/30 Javascript
ECharts地图绘制和钻取简易接口详解
2019/07/12 Javascript
vue集成chart.js的实现方法
2019/08/20 Javascript
在 Vue 中编写 SVG 图标组件的方法
2020/02/24 Javascript
JavaScript禁止右击保存图片,禁止拖拽图片的实现代码
2020/04/28 Javascript
深入探究Django中的Session与Cookie
2017/07/30 Python
Python的地形三维可视化Matplotlib和gdal使用实例
2017/12/09 Python
Python机器学习k-近邻算法(K Nearest Neighbor)实例详解
2018/06/25 Python
Python小工具之消耗系统指定大小内存的方法
2018/12/03 Python
Python3批量生成带logo的二维码方法
2019/06/24 Python
基于django传递数据到后端的例子
2019/08/16 Python
pytorch 获取层权重,对特定层注入hook, 提取中间层输出的方法
2019/08/17 Python
python ubplot使用方法解析
2020/01/10 Python
python+Selenium自动化测试——输入,点击操作
2020/03/06 Python
CSS3旋转——彩色扇子兼容firefox浏览器
2013/06/04 HTML / CSS
阿里健康大药房:阿里自营网上药店
2017/08/01 全球购物
Hotels.com英国:全球领先的酒店住宿提供商
2019/01/24 全球购物
自荐信需注意事项
2014/01/25 职场文书
廉洁教育学习材料
2014/05/19 职场文书
岗位说明书标准范本
2014/07/30 职场文书
预备党员考察表党小组意见
2015/06/01 职场文书
JavaScript实现登录窗体
2021/06/22 Javascript