文章目录
一、(鼠标)行为链
有时候在页面中的操作可能要有很多步,那么这时候可以使用鼠标行为链类ActionChains来完成。比如现在要将鼠标移动到某个元素上并执行点击事件
actions = ActionChains(driver)
actions.move_to_element(inputTag)
actions.send_keys_to_element(inputTag,'python')
actions.move_to_element(submitTag)
actions.context_click()
actions.click(submitTag)
actions.perform()
还有更多的鼠标相关的操作
• click_and_hold(element):点击但不松开鼠标。
• context_click(element):右键点击。
• double_click(element):双击。
• 更多方法请参考:http://selenium-python.readthedocs.io/api.html
具体使用:
from selenium import webdriver
from selenium.webdriver import ActionChains
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
time.sleep(1)
# 定位输入框
inputTag = driver.find_element_by_id('kw')
# 定位百度一下的按钮
buttonTag = driver.find_element_by_id('su')
#鼠标行为链开始
# 实例化对象
actions = ActionChains(driver)
# 往输入框里面输入内容
actions.send_keys_to_element(inputTag,'浩哥')
time.sleep(1)
# 普通点击行为不要在鼠标行为链里面出现 buttonTag.click()
#点击行为
actions.move_to_element(buttonTag)
actions.click()
# 提交行为链
actions.perform()
#鼠标行为链结束
'''
1 千万不要忘记提交鼠标行为链
actions.perform()
2 需要注意鼠标行为链里面的点击操作
'''
二、selenium设置无界面模式(模板)
# 创建chrome设置对象
options = webdriver.ChromeOptions()
# 设置无界面功能 --headless 浏览器无界面 --xxxx
options.add_argument('--headless')
driver = webdriver.Chrome(options=options)
driver.get('https://maoyan.com/board/4')
三、selenium爬取数据
将使用到的一些方法或属性
drvier.page_source 获取html结构的源码
# selenium提取数据的方式,是以页面最终渲染以后,以前端页面为基准的,和响应内容没有什么关系
drvier.find() 在html结构中查找某个字符串是否存在
drvier.get_attribute('src') 获取节点的属性值
drvier.text 获取节点的文本内容 (子子孙孙)
具体使用:
from selenium import webdriver
import time
# options=webdriver.ChromeOptions()
# options.add_argument('--headless')
#options=options
driver = webdriver.Chrome()
# driver.get('https://www.baidu.com/')
# time.sleep(1)
# # driver.page_source #获取检查的字符串格式
# html = driver.page_source
# print(type(html))
# find() 在html结构中查找某个字符串是否存在
# 数字就证明存在没有什么规律;如果不存在会返回 -1
# print(driver.page_source.find('kw1212313213123132'))
driver.get('https://maoyan.com/board/4')
time.sleep(1)
img_tag = driver.find_element_by_xpath('//*[@id="app"]/div/div/div[1]/dl/dd[1]/a/img[2]')
print(img_tag.get_attribute('src'))
四、案例
4.1selenium获取猫眼电影top100电影信息
问题:使用selenium获取猫眼电影top100电影信息 电影排名 电影名称 主演 上映时间 评分
分析页面结构 选择合适的技术点
1>明确目标的url https://maoyan.com/board/4
2>我们先搞定一页的电影数据 再去搞定其它页的
3>通过分析 数据都是在dl标签里面 dl标签里面每一个dd标签它就是一部电影
细节:
1》翻页的处理
- 当我们点击到最后一页的时候 发现下一页的按钮没有了 就可以判断是最后一页了
2》报错的处理
代码:
from selenium import webdriver
import csv
# # 创建chrome设置对象 程序没有问题在去设置 无界面模式
# options = webdriver.ChromeOptions()
# # 设置无界面功能 --headless 浏览器无界面 --xxxx
# options.add_argument('--headless')
# #selenium获取猫眼电影top100电影信息
driver = webdriver.Chrome()
driver.get('https://maoyan.com/board/4')
def get_one_page():
# 找到这一页的dd标签 千万不要忘记写dd
dd_lst = driver.find_elements_by_xpath('//*[@id="app"]/div/div/div[1]/dl/dd')
single_list = []
for dd in dd_lst:
# text属性 获取当前dd节点的子子孙孙的文本内容
# 视情况而分析 验证我们打印的内容有什么规律吗?如果有 就进一步操作
# print(dd.text) #str类型 要测试其结果是啥
# print('*'*80)
one_film_info_lst = dd.text.split('\n')
item = {}
try:
item['rank'] = one_film_info_lst[0].strip()
item['name'] = one_film_info_lst[1].strip()
item['actor'] = one_film_info_lst[2].strip()
item['time'] = one_film_info_lst[3].strip()
item['score'] = one_film_info_lst[4].strip()
except:
pass
single_list.append(item)
print(item)
return single_list
all_list = []
while True:
single_list = get_one_page()
# if 不是最后一页:
# driver.find_element_by_link_text('下一页').click()
# else:
# driver.quit()
# break
all_list += single_list
try:
# 找不到最后一页 就会抛出异常 此时就证明是最后一页了
driver.find_element_by_link_text('下一页').click()
except Exception as e:
driver.quit()
break
with open('maoyetop100.csv', 'w', encoding='utf-8', newline='') as file_obj:
dictwriter = csv.DictWriter(file_obj, fieldnames=['rank', 'name', 'actor', 'time', 'score'])
dictwriter.writeheader()
dictwriter.writerows(all_list)
4.2selenium爬取京东某商品数据
分析页面结构 选择合适的技术点
1>我们发现 所有的数据都是在一个ul标签 ul标签下面每一个li标签对应的就是一本书。
2>我们拖动 拖动条(滚轮)的时候 页面又加载了数据
代码中 当我们进入这个页面的时候,把这个拖动条拖动一下,拖到最下面,然后等它加载一会儿,等页面元素加载完了之后,我们再去抓取
#每页 上来先加载30个 当我们进行拖动的时候 它又会加载30个 也就是每页其实是60个数据
如何拖动 拖动条?(我们会用到一个 加载js的方法)
细节:
1》翻页的处理
- 当我们点击到最后一页的时候 发现下一页的按钮还有 要用find()方法
2》如何拖动 拖动条
3》报错的处理
代码:
from selenium import webdriver
import time
class JdSpider():
def __init__(self):
# 设置无界面
self.options = webdriver.ChromeOptions()
# 设置无界面功能 --headless 浏览器无界面 --xxxx
self.options.add_argument('--headless')
self.driver = webdriver.Chrome(options=self.options)
self.driver.get('https://www.jd.com/')
# 定位输入框和按钮
self.driver.find_element_by_xpath('//*[@id="key"]').send_keys('爬虫书')
time.sleep(1)
self.driver.find_element_by_xpath('//*[@id="search"]/div/div[2]/button').click()
time.sleep(1)
def pares_html(self):
# 进入这个页面的时候,把这个拖动条拖动一下,拖到最下面
# 0 是从去起始位置开始 document.body.scrollHeight 整个窗口的高度 模板!
self.driver.execute_script(
'window.scrollTo(0,document.body.scrollHeight)'
)
time.sleep(2)
# 提取数据 千万不要忘记写li
li_lst = self.driver.find_elements_by_xpath('//*[@id="J_goodsList"]/ul/li')
for li in li_lst:
# print(li.text)
# print('*'*50)
try:
item = {}
item['price'] = li.find_element_by_xpath('.//div[@class="p-price"]/strong').text.strip()
item['name'] = li.find_element_by_xpath('.//div[@class="p-name"]/a/em').text.strip()
item['commit'] = li.find_element_by_xpath('.//div[@class="p-commit"]/strong').text.strip()
item['shop'] = li.find_element_by_xpath('.//div[@class="p-shopnum"]/a').text.strip()
print(item)
except Exception as e:
print(e)
def main(self):
while True:
self.pares_html()
#
if self.driver.page_source.find('pn-next disable') == -1:
self.driver.find_element_by_xpath('//*[@id="J_bottomPage"]/span[1]/a[9]').click()
time.sleep(1)
else:
self.driver.quit()
break
if __name__ == '__main__':
spider = JdSpider()
spider.main()
总结:
一些细节:
- 拖动条的处理
- 无界面模式
- 翻页灵活处理(2种)
- 报错的解决(指爬取的数据的处理)