使用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之编写类之四再论继承
Oct 11 Python
CentOS中使用virtualenv搭建python3环境
Jun 08 Python
PyCharm使用教程之搭建Python开发环境
Jun 07 Python
Python模块结构与布局操作方法实例分析
Jul 24 Python
解决Django的request.POST获取不到内容的问题
May 28 Python
使用Python实现毫秒级抢单功能
Jun 06 Python
Python日志无延迟实时写入的示例
Jul 11 Python
Python实现Mysql数据统计及numpy统计函数
Jul 15 Python
Python3 批量扫描端口的例子
Jul 25 Python
Python json模块与jsonpath模块区别详解
Mar 05 Python
Python调用JavaScript代码的方法
Oct 27 Python
对象析构函数__del__在Python中何时使用
Mar 22 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合并数组array_merge函数运算符加号与的区别
2008/10/31 PHP
实例讲解如何在PHP的Yii框架中进行错误和异常处理
2016/03/17 PHP
PHP输出XML格式数据的方法总结
2017/02/08 PHP
filters.revealTrans.Transition使用方法小结
2010/08/19 Javascript
Ajax 数据请求的简单分析
2011/04/05 Javascript
Javascript定义类(class)的三种方法详解
2015/03/13 Javascript
JavaScript中 ES6 generator数据类型详解
2016/08/11 Javascript
JavaScript 中对象的深拷贝
2016/12/04 Javascript
简单实现jQuery弹幕效果
2017/05/06 jQuery
解决vue-cli中stylus无法使用的问题方法
2017/06/19 Javascript
js canvas实现画图、滤镜效果
2018/11/27 Javascript
vue项目创建并引入饿了么elementUI组件的步骤
2019/04/11 Javascript
vue百度地图 + 定位的详解
2019/05/13 Javascript
vue中实现弹出层动画效果的示例代码
2020/09/25 Javascript
[53:29]完美世界DOTA2联赛循环赛 DM vs Matador BO2第二场 11.04
2020/11/05 DOTA
python使用mysqldb连接数据库操作方法示例详解
2013/12/03 Python
Python实现获取域名所用服务器的真实IP
2015/10/25 Python
Python图算法实例分析
2016/08/13 Python
python实时分析日志的一个小脚本分享
2017/05/07 Python
Windows上使用Python增加或删除权限的方法
2018/04/24 Python
Python正则匹配判断手机号是否合法的方法
2020/12/09 Python
python 与服务器的共享文件夹交互方法
2018/12/27 Python
Python pycharm 同时加载多个项目的方法
2019/01/17 Python
实例讲解Python脚本成为Windows中运行的exe文件
2019/01/24 Python
Python3实现统计单词表中每个字母出现频率的方法示例
2019/01/28 Python
python psutil模块使用方法解析
2019/08/01 Python
Python Gitlab Api 使用方法
2019/08/28 Python
简单了解如何封装自己的Python包
2020/07/08 Python
携程英文网站:Trip.com
2017/02/07 全球购物
澳大利亚儿童精品仓库:Goo & Co.
2019/06/20 全球购物
如何将字串String转换成整数int
2015/02/21 面试题
2014机关党员干部“正风肃纪”思想汇报
2014/09/15 职场文书
药店采购员岗位职责
2014/09/30 职场文书
学生保证书
2015/01/16 职场文书
Python Django ORM连表正反操作技巧
2021/06/13 Python
微信小程序实现轮播图指示器
2022/06/25 Javascript