title: 爬虫系列之selenium
date: 2019-04-19 16:33:24
tags: 爬虫
categories: 爬虫
toc: true
一、什么是selenium
Selenium 是什么?一句话,自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium 的插件,那么便可以方便地实现Web界面的测试。换句话说叫 Selenium 支持这些浏览器驱动。Selenium支持多种语言开发,比如 Java,C,Ruby等等,而对于Python,当然也是支持的!
二、selenium的基本使用
声明浏览器的对象
browser=webdriver.Chrome()
browser.get("https://www.jd.com/")
browser.find_element_by_id('key').send_keys('ipad')
browser.find_element_by_class_name('button').click()
设置延时
wait = WebDriverWait(browser, 10)
wait.until(EC.presence_of_element_located((By.XPATH, btn_water_element)))
# 常见的API
# 1.跳转至指定网页
browser.get("https://www.baidu.com")
#
# # 2.获取当前页面标题内容
# print(browser.title)
#
# # 3.获取当前网页地址
# print(browser.current_url)
#
# # 4.获取当前页面元素
# print(browser.page_source)
#
# # 5.回退到之前打开的页面
# browser.back()
#
# # 6.前进到回退之前的页面
# browser.forward()
#
# # 7.获取页面上的元素
# #寻找id为’su’的元素
# browser.find_element_by_id('su')
#
# #寻找name为’wd’的元素
# browser.find_element_by_name('wd')
#
# #寻找链接文本信息为’贴吧’的元素
# browser.find_element_by_link_text('贴吧')
#
# #寻找classname为’c-tips-container’的元素
# browser.find_element_by_class_name('c-tips-container')
#
# #寻找xpath中带有id名为kw的元素
# browser.find_element_by_xpath('//*[@id="kw"]')
#
# #寻找标签名带有’div’的元素
# browser.find_element_by_tag_name('div')
#
# #寻找链接文本部分带有’新’的元素
# browser.find_element_by_partial_link_text('新')
# # 8.对寻找到的元素进行一些操作
#
# # 以百度搜索首页为例,进行操作:
# #在百度文本搜索框内输入内容Python Selenium
# browser.find_element_by_name('wd').send_keys("PythonSelenium")
# # #清空文本搜索框的所有内容
# # browser.find_element_by_name('wd').clear()
# # 点击搜索按钮
# browser.find_element_by_id('su').click()
# # 提交搜索按钮,这里效果同点击搜索按钮
# browser.find_element_by_id('su').submit()
# 9.模拟鼠标的操作
# 以百度搜索首页为例,进行操作:
#
# 需要引入包ActionChains:
from selenium.webdriver.common.action_chains import ActionChains
#在搜索文本框利用context_click()进行鼠标右击,perform() 是执行方法的语句
# ActionChains(browser).context_click(browser.find_element_by_id('kw')).perform()
#在搜索文本框利用double_click()进行双击, perform() 是执行方法的语句
ActionChains(browser).double_click(browser.find_element_by_id('kw')).perform()
#利用drag_and_drop(source,target)从搜索文本框移动到点击按钮, perform() 是执行方法的语句
ActionChains(browser).drag_and_drop(browser.find_element_by_id('kw'),browser.find_element_by_id('su')).perform()
#利用move_to_element()停留在文本搜索框上, perform() 是执行方法的语句
ActionChains(browser).move_to_element(browser.find_element_by_id('kw')).perform()
#利用click_and_hold()可以点击并且停留在搜索按钮上, perform() 是执行方法的语句
ActionChains(browser).click_and_hold(browser.find_element_by_id('su')).perform()
# 10. 模拟键盘操作
#
# 以百度搜索首页为例,进行操作:
#
# 需要引入包Keys:
browser.find_element_by_id('kw').send_keys(Keys.BACK_SPACE)#Backspace键
browser.find_element_by_id('kw').send_keys(Keys.SPACE)#Space键
browser.find_element_by_id('kw').send_keys(Keys.DELETE)#Delete键
browser.find_element_by_id('kw').send_keys(Keys.CONTROL,'a')# CTRL + A
browser.find_element_by_id('kw').send_keys(Keys.CONTROL,'x')# CTRL + X
browser.find_element_by_id('kw').send_keys(Keys.CONTROL,'v')# CTRL + V
browser.find_element_by_id('kw').send_keys(Keys.ENTER)#ENTER键
browser.find_element_by_id('kw').send_keys(Keys.CONTROL,'c') # CTRL + C
browser.find_element_by_id('kw').send_keys(Keys.TAB)# TAB键
# 11. 智能等待方法
#
# 需要引入包 WebDriverWait
from selenium.webdriver.support.ui import WebDriverWait
WebDriverWait(browser,10).until(lambda driver :browser.find_element_by_id('kw'))
#利用WebDriverWait方法 等待10秒,直到id为’kw’控件出现
browser.implicitly_wait(30)#在页面上隐式等待30 秒
import time #引入time包
time.sleep(5) # 等待5秒
三、selenium+bs4爬虫实战
我们前面学习到了beautiful soup,现在我们利用我们刚学的selenium和beautiful soup 来爬取一些局部动态网页。比如:https://www.huya.com/l ,这是虎牙直播的直播页面网址,我们要爬取每个直播房间的房间名,主播名字,热度还有游戏的分类
分析网站
我们先点击网址,进入目标网站,如下图所示:
我们点击页面最下方的一下按钮,我们会发现,网站的网址并不会发生变化,因此我么如果按照常规的爬取方法,肯定无法获得我们所想要的全部数据,所以我们就要用到我们如今刚学的selenium技术。
我们分析网站的源码,找到下一页按钮所对应的源码:
我们只需要在爬取一页的所有内容之后,点击下一页的按钮,然后继续爬取即可,因此我们需要用到我们的selenium技术
那么问题来了,我们要怎样判断条件的终止呢?
我们可以设置一个循环,一直点击下去,直到最后一页,我们再点击下一页时:
if browser.page_source.find('laypage_next') != -1:
# 判断访问的url是否结束,一页最后还有没有下一页,通过寻找下一页的<a>标签
browser.find_element_by_xpath('//a[@class="laypage_next"]').click()
# 如果找到下一页的<a>标签,就点击.click()
else:
# 如果没有程序结束
break
没有找到下一页的标签就停止循环,就可以达到我们所需要的了。
最终的代码:
from bs4 import BeautifulSoup
from selenium import webdriver
from time import sleep
def huyaspider():
browser = webdriver.Chrome()
browser.get('https://www.huya.com/l')
num=1
while True:
print('第' + str(num) + "页----------------------------------------------------------------")
num += 1
sleep(2)
html = browser.page_source
soup = BeautifulSoup(html, 'lxml')
items = soup.find_all('li', class_='game-live-item')
for item in items:
name = item.find('a', ['title']).get_text()
zb_name = item.find('i', class_='nick').get_text()
js_num = item.find('i', class_='js-num').get_text()
group = item.find('span', class_='game-type').get_text()
name = "房间名:" + str(name) + '\n'
zb_name = "主播名:" + str(zb_name) + '\n'
js_num = "直播间热度:" + str(js_num) + '\n'
group = "游戏类别:" + str(group) + '\n'
data = name + zb_name + js_num + group
f.writelines(data + '------------------' + '\n')
if browser.page_source.find('laypage_next') != -1:
# 判断访问的url是否结束,一页最后还有没有下一页,通过寻找下一页的<a>标签
browser.find_element_by_xpath('//a[@class="laypage_next"]').click()
# 如果找到下一页的<a>标签,就点击.click()
else:
# 如果没有程序结束
break
filename = '虎牙直播数据统计.txt'
f = open(filename, 'w', encoding='utf-8')
#
huyaspider()
f.close()
print('保存成功。')
最后是我们的爬取结果(只截取了部分数据):
房间名:虎牙德比 BA黑凤梨 2:2 QGhappy
主播名:KPL职业联赛
直播间热度:613.3万
游戏类别:王者荣耀
------------------
房间名:【万人狙击】王牌3星
主播名:DK-不求人
直播间热度:223.5万
游戏类别:刺激战场
------------------
房间名:峡谷练练!
主播名:蛇哥colin
直播间热度:103.6万
游戏类别:英雄联盟
------------------
房间名:乔治巴顿 出去浪一圈
主播名:集梦会长
直播间热度:68.4万
游戏类别:户外
------------------
房间名:【电台】那晚她居然对我......
主播名:正恒pop-小仔
直播间热度:49.5万
游戏类别:星秀
------------------
房间名:董导 虎牙棋圣 冲皇后 竞猜前3
主播名:狂鸟丶董小飒-90327
直播间热度:134.8万
游戏类别:主机游戏
------------------
至此,我们的selenium学习也就大功告成了!