文章目录
- 1. 问题引入
- 2. 屏幕滚动问题
- 3. 滚动停止的方法
- 4. 案例
1. 问题引入 现在的网页都是采用ajax加载的,如果我们要用selenium爬取网页的全部内容,就必须等待网页彻底加载完毕。而一页很显然不能加载完,那就需要拖动滚动条,直到所有内容加载完。而且,如果你爬取的时多个网页,那么你要控制住,当页面内容加载完后停止滚动。然后开始获取页面内容并解析爬取。本文就是介绍这两点内容的。我查找了许多帖子和博客,最终没有能够如愿解决。后来结合查到的信息内容和自己的思想解决了问题。全用的python和selenium知识。如你有更好的方法欢迎留言,留链接,一定借鉴。
2. 屏幕滚动问题 滚屏问题,我查了很多帖子,都是操作滚动条。而我的案例滚动条时隐藏的,很多次都没有成功。后来采用了send_keys(Keys.PAGEUP)解决了问题。具体代码如下:
from selenium import webdriver
from selenium.webdirver.commen.keys import Keys
import time
# 实例化web驱动
driver = webdriver.Chrome()
# 你要爬取的网页地址,建议换成自己的,我这个需要扫码登录
url='https://www.pypypy.cn/#/apps/1/lecture/5cd9766a19bbcf00015547d0
driver.get(url)
time.sleep(2) # 让页面加载完毕再操作,避免无效操作
driver.find_element_by_tag_name('body').click()# 这一步的意思就是在获得的页面上点击一下,这步很关键,如果不点击,后面的翻页动作将不会进行
for i in range(20):
driver.find_element_by_tag_name('body').send_keys(Keys.PAGE_UP) # 向上翻页20次,暂时先用这种办法,后面会介绍更好的控制方法
driver.quit() # 退出网页
这是页面滚动方法,如果你的电脑支持快捷键组合“Ctrl+Home”快速回到页面首,那就直接发送这个组合键将更快。无奈我的这个组合键时“Fn+Home”,而Selenium中没有这个组合键,所以就只能用PageUp多翻几次了。
3. 滚动停止的方法 【解决页面滚动并滚动停止时间问题案例】我查了一下网上提供的方法,有判断页面是否加载完毕的方法,嫌麻烦,关键是我没有操作成功。故而又从一个人的建议那里得到了灵感。可以找这个页面经常出现的标签,大部分是“div”标签,可以len一下当前的标签数目,然后让页面滚动一阵子,再次len一下此时的标签数,如果不相等,那么肯定还没有加载完啦。所以有了下面的代码。
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
# 这是我要爬取的页面的url,构成一个列表,你要换成自己的哦
urls= ['https://www.pypypy.cn/#/apps/2/lecture/5dc547a8faeb8f00015a0ea8','https://www.pypypy.cn/#/apps/2/lecture/5dc547a9faeb8f00015a0ead','https://www.pypypy.cn/#/apps/2/lecture/5dc547aafaeb8f00015a0eb0']
# 实例化web驱动
driver = webdriver.Chrome()
for url in urls:
driver.get(url)
time.sleep(1)让页面加载完毕,具体等待时间根据网页反应时间定
driver.find_element_by_tag_name('body').click()# 点击一下页面
s_num = 1# 后面用来记初始div标签的数目,暂时赋值为1为了启动循环
f_num = 0# 记录滚动后div标签的数目
while s_num > f_num:# 开启while循环,如果满足这个条件就一直循环下去,直到页面加载完毕后s_num== f_num 循环结束
source = driver.page_source# 获取网页内容
soup = BeautifulSoup(source,'lxml')# 解析
elements = soup.find_all('div')# 查找当前所有的div
f_num = len(elements)# len()函数记录div数目,并赋值给f_num
driver.find_element_by_tag_name('body').click()# 点击一下,后面要开始翻页了,每次开始翻页前都要点一下啊
for i in range(50):# 滚动50次,一般滚动几次div数肯定就不一样了
driver.find_element_by_tag_name('body').send_keys(Keys.PAGE_UP)# 翻页
time.sleep(0.01) # 每次翻页时间间隔,你也可以自己设定
time.sleep(0.1) # 页面加载时间
source = driver.page_source# 再次获取网页内容
soup = BeautifulSoup(source, 'lxml')# 解析
elements = soup.find_all('div') # 查找滚动后的所有div标签
s_num = len(elements)# 结束时的元素数赋值给 s_num
以上是判断页面是否加载完毕,加载完毕后即停止翻动。
4. 案例 下面是我的一个案例,我要爬取多个网页,并且需要扫码登录的。爬取网页的文字内容,并且保存为txt文档。仔细看注释:
# 导入必要模块
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
# 实例化驱动
driver = webdriver.Chrome()
url_0 = 'https://www.pypypy.cn/#/app-center'# 登录页面的网址
# 要爬取的网页的网址列表
urls= ['https://www.pypypy.cn/#/apps/2/lecture/5dc547a8faeb8f00015a0ea8','https://www.pypypy.cn/#/apps/2/lecture/5dc547a9faeb8f00015a0ead','https://www.pypypy.cn/#/apps/2/lecture/5dc547aafaeb8f00015a0eb0']
# 登录页面
driver.get(url_0)
time.sleep(15)# 趁这个时间扫码登录,由于网页记住了cookie,后面再循环登录其他网页的时候就不需要扫码了
k = 0# 用来计算,写入文章标题时传入。
for url in urls_s:
driver.get(url)
driver.implicitly_wait(5) # 隐式等待,实际不需要5秒,什么时候加载完页面什么时候进行下一步
driver.maximize_window()# 窗口最大化
driver.implicitly_wait(5)
s_num = 1
f_num = 0
while s_num > f_num:
source = driver.page_source
soup = BeautifulSoup(source,'lxml')
elements = soup.find_all('div')
f_num = len(elements)# 开始的元素数
driver.find_element_by_tag_name('body').click()
# 先翻页一阵子,这里我定义50次
for i in range(50):
driver.find_element_by_tag_name('body').send_keys(Keys.PAGE_UP)
time.sleep(0.01)
time.sleep(0.1)
source = driver.page_source
soup = BeautifulSoup(source, 'lxml')
elements = soup.find_all('div')
s_num = len(elements)# 结束时的元素数
time.sleep(1)# 全部加载完毕了,等待一下,保证下面要获取网页内容的完整性
# 获取网页内容
pageSource = driver.page_source
soup = BeautifulSoup(pageSource, 'lxml') # 解析
contents = soup.find_all('div', class_="plugin-markdown-chat") # 所要的字符串藏再这个标签里,把所有此类标签找出来,结果是列表
with open('python_spider_0.txt', 'a', encoding='utf_8') as f:# 新键文本写入对象
f.write('\n')# 写入前换行
f.write('# **=第{}关=** #'.format(k))# 标题
f.write('\n')# 标题后换行
for i in contents:# 遍历 contents列表
f.write(i.text)#提取出字符串文本并写入
f.write('\n')# 这里每句换行
f.write('*=' * 100) # 写完一篇后画分割线
k += 1# 计数
time.sleep(1)# 开始下个页面前的短暂等待
print('over')# 所有页面爬取完的提示
time.sleep(1)# 1秒后退出浏览器
driver.quit()# 退出
以上的这个案例用到了前面介绍的所有内容,重复的步骤就不再注释。如有更好的建议欢迎留言,相互学习。
推荐阅读
- python|python爬虫实战演示
- 爬虫|通过爬虫使用百度翻译
- python|Python学习记录-项目案例实现(爬虫篇 03)
- pyppeteer|爬虫(解决pyppeteer初始化中的ssl错误)
- 爬虫|利用python一键修改host 一键上网
- 程序员|爬取某宝4000条数据,用Python做了一个 “月饼“ 可视化大屏,过中秋
- Python-爬虫|Python爬虫(selenium)
- python|Python爬虫自动化爬取b站实时弹幕实例方法
- python|python写一个简单的爬虫程序(爬取快手)(附源码)