抓取动态网页(selenium1.使用selenium抓取动态图片本次抓取的流程确认)
优采云 发布时间: 2021-09-13 23:05抓取动态网页(selenium1.使用selenium抓取动态图片本次抓取的流程确认)
文章directory
本章将带大家使用selenium抓取一些动态加载的页面,让大家体验selenium的用处
1.使用selenium抓取动态图片
本次拍摄的图片为百度图片中安吉拉的相关图片
import time
import requests # 使用requests下载图片
from urllib import request # 下载图片
from bs4 import BeautifulSoup # 使用bs4解析
from selenium import webdriver # 自动化测试工具
# 配置下载的图片的地址, 文件夹需要先创建好
IMAGE_PATH = './images/'
# 实例化驱动程序的Chrome对象, driverpath: 驱动的路径
browser = webdriver.Chrome(r'driverpath')
# 定制请求头信息
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
"Chrome/74.0.3729.108 Safari/537.36",
}
# 打开百度图片页面
browser.get('https://image.baidu.com/')
# 获取输入框并向输入框内输入数据
input_box = browser.find_element_by_id('kw')
input_box.send_keys('安琪拉')
time.sleep(2)
# 点击搜索按钮获取响应输入
button = browser.find_element_by_class_name('s_search')
button.click()
time.sleep(1)
# 下拉滚动条, 循环多次下拉, 可以获取到更多的图片
for i in range(3):
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
time.sleep(1.5)
# 获取网页的str源代码
response = browser.page_source
# 实现数据解析--使用测试工具获取到的源码就是str类型,不需要再使用text获取文本数据
soup = BeautifulSoup(response, 'lxml')
li_list = soup.select('.imgpage ul li')
for li in li_list:
# li内的data-objurl属性存储的是图片的地址
href = li['data-objurl']
# 首先使用urllib模块下的request.urlretrieve下载, 此处我注释了, 大家可以尝试一下
# request.urlretrieve(href, IMAGE_PATH+'%s.jpg' % li_list.index(li))
# print('正在下载地址为%s的图片...' % href)
# time.sleep(0.5)
# 使用requests模块下载 -- 需要自己写入文件,因为requests没有自带的下载方法
image_response = requests.get(url=href, headers=headers)
# 写入文件必须使用二进制写入
with open(IMAGE_PATH + "%s.jpg" % li_list.index(li), 'wb') as f:
# 访问的是图片页面,图片是二进制流,使用content获取
f.write(image_response.content)
# 循环下载完成后退出
browser.quit()
2.使用 selenium 捕获动态数据
获取动态数据我在找雪球网,爬取雪球网首页推荐数据,以及雪球网地址
2.1 分析爬虫页面,制定爬虫流程
确认网址
我这里看到的是一样的数据,是当前的url,可以点击Headers复制url
如上图,数据已经存在,但是你往下看抓包会发现只有几条数据,所以需要用selenium打开当前页面配合用js实现页面下拉获取更多数据
分析获取的数据(xpath或bs4),得到需要的数据
对数据进行封装和持久化,存储在文件或数据库中(后面会讲)
2.2 编写爬虫代码并进行页面爬取
import time
import json # 用于格式化存入文件
from selenium import webdriver # 自动化测试工具
from lxml import etree # 使用xpath解析
def spider_snowball():
"""
1.爬取雪球网,获取url
2.使用自动化测试工具打开雪球网
3.需要使用自动化测试工具循环下拉滚动条三次,获取到动态加载的数据
4.然后使用自动化测试工具点击加载更多的button按钮,来获取到更多的数据
5.对获取到的数据进行解析,拿取需要的数据
6.将数据循环以词典添加到列表中
7.将列表数据写入到文件中,并且需要将列表转换为json字符串
"""
# 开始时间, 用于测试爬虫的时长
start_time = time.time()
# 雪球网的url, 默认就为推荐数据
url = 'https://xueqiu.com'
# 定制请求头信息
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
"Chrome/74.0.3729.108 Safari/537.36",
}
# 实例化浏览器对象,以谷歌浏览器运行, driverpath: 自己驱动的存放路径
browser = webdriver.Chrome(r'driverpath')
# 打开对应的url
browser.get(url)
# 下拉滚动条三次, 三次之后就需要点击加载更多的按钮, 可自己下拉查看
for i in range(3):
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
time.sleep(1.5)
# 获取加载更多的按钮
button = browser.find_element_by_class_name('AnonymousHome_home__timeline__more_6RI')
try:
# 循环点击这个按钮,并且下拉获取到更多的数据, 此处循环自行设置, 可以不必循环太多次
for i in range(100):
# 点击这个按钮
button.click()
# 点击按钮之后会展示更多的数据,然后继续下拉滚动条来获取加载更多按钮
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
time.sleep(2)
except Exception as e:
print('出错了:', e)
else:
# 如果没有出错,那么则获取到了全部(大量)的数据,下面要对数据进行解析,取出所需数据
# 获取到的网页源码就是str类型,不需要再使用text获取html文本数据
tree = etree.HTML(browser.page_source)
# 获取到所有的a标签
a_list = tree.xpath('//div[@class="AnonymousHome_home__timeline__item_3vU"]/h3/a')
result_list = []
for a in a_list:
result_dict = dict()
# 标签中的文字可直接使用text获取文本或者再次使用xpath匹配
title = a.text
# 因为xpath匹配出来后的数据是放在列表中,所以要从列表中拿出来
href = url + a.xpath('./@href')[0]
# 将数据添加到字典中
result_dict["title"] = title
result_dict["url"] = href
# 将字典添加到列表中
result_list.append(result_dict)
# 此处循环完毕后,列表中有多个字典,可以将列表写入文件(数据库)中,以便查看数据
with open('xue_qiu.json', 'w', encoding='utf-8') as f:
# 写入文件要将python格式转换为json字符串写入
f.write(json.dumps(result_list, ensure_ascii=False, indent=2))
# 退出浏览器
browser.quit()
end_time = time.time()
# 打印爬取数据的总时长
print("总耗时:%d" % (end_time-start_time))
if __name__ == '__main__':
spider_snowball()
3.Summary
相信如果你用上面的代码自己抓取数据,你就会知道selenium的方便了。如果你不使用selenium去抓取一些数据,你抓取可能会很不方便,但是selenium也有自己的缺点,那就是效率不高。就像上面爬的雪球网一样,我自己测试的时候用了220s。有时也可以选择抓取js包进行数据分析(后面会有案例),当然,如果用其他方法拿不到数据,使用selenium也是不错的选择。