文章目录
- 一.使用selenium模拟真人登陆账号
- 1. 环境配置
- a.python >= 3.6
- b.火狐浏览器
- c.火狐浏览器驱动器
- 2.代码
- a.模拟真人登陆
- b.利用刚刚登陆验证的账号, 重新访问得到cookie验证码
- c1. 使用上面得到的cookie验证码重新进入网页,并保存网页数据
- c2. 点击需要点击的位置
- 二. selenium
- a.selenium 的定位方法
- b.selenium方法
- 应用1
- 1. 打开浏览器输入网址
- 2.登陆账号
- 3.进入博客
- 4.浏览博客第一条
- 5. 刷新退出等试验
- 应用2. 获取博客列表
一.使用selenium模拟真人登陆账号
1. 环境配置
a.python >= 3.6
需要的包
- from selenium import webdriver
- import requests
- import json
- import time
c.火狐浏览器驱动器
之所以需要驱动器, 因为模拟真人操作浏览器访问网址, 因此需要利用Python调用打开浏览器, 这就需要驱动器了
- 安装三大浏览器驱动driver
注意:下载解压后,将geckodriver.exe
复制到Python的安装目录,如下图 。
然后再将Python和火狐浏览器安装目录添加到系统环境变量的Path下面。
2.代码
a.模拟真人登陆
from selenium import webdriver
import requests
import json
import time
# 使用selenum模拟登陆,
username = "xxxx@163.com"
password = "12345678"
driver = webdriver.Firefox() # 打开浏览器
driver.get('https://www.easyke.com/i/experts/login') # 浏览器浏览网址
#用户名的定位
driver.find_element_by_id("easyke_mentor_email").clear() # 搜索id为改值, 清楚
driver.find_element_by_id("easyke_mentor_email").send_keys(username) # 给值为用户名
driver.find_element_by_id("easyke_mentor_password").clear()
driver.find_element_by_id("easyke_mentor_password").send_keys(password) # 给密码
time.sleep(8) # 这里等待网站反映
driver.find_element_by_id('next_step').click()
time.sleep(4)
下图可以定位密码输入栏的具体参数
<input autofocus="autofocus"
placeholder="Email"
class="sign_in_input validate[required] c-form-field c-form-field--primary c-form-field--lg"
type="text"
value="" # 理论上, 就是通过网页用户改变这个value值, 然后在发送给服务器,进行验证账户
name="easyke_mentor[email]"
id="easyke_mentor_email"> # 这里的id就是独一无二的定位
b.利用刚刚登陆验证的账号, 重新访问得到cookie验证码
driver.get('https://www.easyke.com/i/experts/dashboard')
#获取cookies, 将数据字典保存到json
post = {}
cookie_items = driver.get_cookies()
for cookie_item in cookie_items:
post[cookie_item['name']] = cookie_item['value']
cookie_str = json.dumps(post)
with open('cookie.json', 'w', encoding='utf-8') as f:
f.write(cookie_str)
c1. 使用上面得到的cookie验证码重新进入网页,并保存网页数据
# 使用上面得到的验证码重新进入网页
from bs4 import BeautifulSoup
import requests
target = 'https://www.easyke.com/i/experts/dashboard'
header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64;rv:75.0) Gecko/20100101 Firefox/75.0"}
with open('cookie.json', 'r', encoding='utf-8') as f:
cookies = json.loads(f.read())
req = requests.get(url=target, cookies=cookies, headers=header)
req.raise_for_status()
html = req.text
with open("save.html", "w", encoding="utf-8") as fd:
fd.write(html)
c2. 点击需要点击的位置
如下图, 进入页面后是open页面, 这里需要点击need Answer, 因此需要使用selenium点击这里, 通过查看html元素, 发现这里的class名字是need_answers
, 因此使用定位class的方法定位并点击
driver.get('https://www.easyke.com/i/experts/dashboard')
driver.find_element_by_class_name('need_answers').click()
d.接下来就是得到网址内容, 通过BeautifulSoup进行数据的提取, Python.re的使用了, 见下讲, 有问题可私聊
二. selenium
a.selenium 的定位方法
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
前八种是大家都熟悉的,经常会用到的
id定位:find_element_by_id(self, id_)
name定位:find_element_by_name(self, name)
class定位:find_element_by_class_name(self, name)
tag定位:find_element_by_tag_name(self, name)
link定位:find_element_by_link_text(self, link_text)
partial_link定位find_element_by_partial_link_text(self, link_text)
xpath定位:find_element_by_xpath(self, xpath)
css定位:find_element_by_css_selector(self, css_selector)
b.selenium方法
- 发起请求:driver.get(url)
- 获取请求网页的标题:driver.title()
- 获取某元素ID中的内容:find_element_by_id(‘id名称’)
- 获取某元素ID中的所有内容:find_elements_by_id(‘id名称’)
- 获取某xpath中的内容:find_element_by_xpath(xpath)
- 获取某xpath中的内容:find_elements_by_xpath(xpath)
- 根据准确文字获取定位:find_element_by_link_text(link_text)
- 根据准确文字获取定位:find_elements_by_link_text(link_text)
- 根据模糊文字获取定位:find_element_by_partial_link_text(self, link_text)
- 根据模糊文字获取定位:find_elements_by_partial_link_text(self, link_text)
- 通过标签名进行定位:find_element_by_tag_name(name)
- 通过标签名进行定位:find_elements_by_tag_name(name)
- 通过class标签查找:find_element_by_class_name(name)
- 通过class标签查找:find_elements_by_class_name(name)
- find_element_by_css_selector(self, css_selector)
- find_elements_by_css_selector(self, css_selector)
- 输入内容:send_keys(*value)
- 判断某个元素是否存在:is_displayed()
- 获取当前driver的url:current_url
- 获取当前driver的html:page_source
- 关闭当前窗口,或最后打开的窗口:close()
- 关闭所有窗口:quit()
- 获取当前窗口:current_window_handle
- 获取所有窗口:window_handles
- 最大化窗口:maximize_window
- 切换窗口:switch_to()
- 切换到指定窗口:switch_to_window(self, window_name)
- switch_to_active_element(self)
- switch_to_frame(self, frame_reference)
- switch_to_frame(self, frame_reference)
- switch_to_default_content(self)
- switch_to_alert(self)
- 返回上一页面: back(self)
- 返回上一页面:forward(self)
- 刷新页面:refresh(self)
- 一种情况就是,当你从一个父页面跳转到子页面进行操作,操作完之后没有“返回”之类的按钮或链接,重新进入父- 页面又很麻烦,back()可以帮你。forward()与此类似,相对没有back()那么常用
- 得到cookies信息:get_cookies()
- 得到指定的cookie信息:get_cookie(self, name)
- 删除指定的cookie信息:delete_cookie(self, name)
- 删除所有的cookie信息:delete_all_cookies(self)
- 添加cookie信息,实现自动登录:add_cookie(self, cookie_dict)
- 等待页面加载时间:implicitly_wait(self, time_to_wait)
- 设置等待超时时间:set_script_timeout(self, time_to_wait)
- 设置等待超时时间:set_page_load_timeout(self, time_to_wait)
- 根据元素查找:find_element(‘元素类型’,‘元素值’)
- 根据元素查找:find_elements(‘元素类型’,‘元素值’)
- 测试脚本分布到哪台服务器或设备进行测试:desired_capabilities(self)
- 截图:get_screenshot_as_file(self, filename)
- save_screenshot(self, filename)
- 这个是获取屏幕截图,保存的是二进制数据:get_screenshot_as_png(self)
- 获取屏幕截图,保存的是base64的编码格式,在HTML界面输出截图的时候,会用到:get_screenshot_as_base64- (self)
- 设置窗口的大小:set_window_size(self, width, height, windowHandle=‘current’)
- 得到窗口的大小:get_window_size(self, windowHandle=‘current’)
- 设置窗口的打开的坐标:set_window_position(self, x, y, windowHandle=‘current’)
- 得到窗口当前的坐标:get_window_position(self, windowHandle=‘current’)
- 设置窗口打开的样式:get_window_rect(self)
- set_window_rect(self, x=None, y=None, width=None, height=None)
- file_detector(self, detector)
- orientation(self)
- orientation(self, value)
- application_cache(self)
- 获取当前driver的日志类型:log_types(self)
- 得到当前driver的日志:get_log(self, log_type)
- execute_async_script():
- current_url:获取当前请求的URL
- page_source
- close
- quite() # 关闭网页浏览器
- current_window_handle
- window_handles
- maximize_window
- switch_to_window:切换窗口
- switch_to_active_element
- switch_to_alert:
- back # 后退
- forward # 前进
refresh:刷新
get_cookies:获取当前driver的所有cookie
get_cookie:得到所有cookie
delete_cookie:删除cookie
delete_all_cookies:删除所有cookie
implicitly_wait:等待加载时间
set_script_timeout:设置间隔时间
set_page_load_timeout:页面加载完成时间
find_element:查找元素
find_elements:
desired_capabilities:
get_screenshot_as_file(self, filename):截图功能
get_screenshot_as_png:
get_screenshot_as_base64:
set_window_size(self, width, height, windowHandle=‘current’)
:模仿人为拖动窗口的大小
get_window_size(self, windowHandle=‘current’):得到窗口的大小
set_window_position(self, x, y, windowHandle=‘current’)
get_window_position(self, windowHandle=‘current’)
get_window_rect
set_window_rect(self, x=None, y=None, width=None, height=None)
get_log:获取drive日志 - 获取alert弹框中的文本
alert_text = driver.switch_to.alert
sleep(1)
text = alert_text.text
print(text)
1. 打开浏览器输入网址
from selenium import webdriver
import requests
import json
import time
# 使用selenum模拟登陆,
username = "13096908985"
password = "zhaojia7"
driver = webdriver.Firefox() # 打开火狐浏览器
driver
2.登陆账号
# driver.find_element_by_class_name('text-tab border-right').click()
driver.find_element_by_xpath("//*[text()='账号密码登录']").click() #点击账户密码登陆
#用户名的定位
driver.find_element_by_id("all").clear() # 清楚id为all的值
driver.find_element_by_id("all").send_keys(username) # 建立值为username
driver.find_element_by_id("password-number").clear()
driver.find_element_by_id("password-number").send_keys(password)
time.sleep(8)
# driver.find_element_by_class_name("form-submit col-xs-12 col-sm-12 col-pr-no col-pl-no").click()
# driver.find_element_by_xpath("//*[text()='登陆']").click()
driver.find_element_by_xpath('//*[@class="btn btn-primary"]').click() # 点击登陆, 登陆对应的class为xx
time.sleep(4)
3.进入博客
# 上面登陆结束, 进入主页
driver.get('h
# driver.title()
4.浏览博客第一条
# 绝对路径定位 存在很大的问题就是如果页面元素一改变元素的xpath也会随之改变,很不稳定,不推荐使用
a = driver.find_element_by_xpath('/html/body/div[6]/main/div[2]/div[1]').get_attribute("innerHTML")
# 标签+属性定位——xpath = "//标签名[@属性='属性值']",*表示所有的标签名
# a = driver.find_element_by_xpath('//*[@class="arget_attribute("innerHTML")
# 当单一的属性无法确定到一个元素时,可以使用组合属性的方式
# a = driver.find_element_by_xpath('//*[@class="articd @data-articleid="89409599"]').get_attribute("innerHTML")
# text()方法定位
# a = driver.find_element_by_xpath('//*[text()=" 双系统安装 win10+Ubuntu18 "]').get_attribute("innerHTML")
# 如果一个元素无法通过自身的属性定位到,那么可以先定位到他的上一级或者上N级,然后再一级一级地找到他
print(a)
'''
Xpath的优缺点
缺点
1、性能差,因为使用这种方式进行定位,webdriver会将整个页面的所有元素进行扫描来找到我们所需的元素,所以当脚本中大量使用XPath方式定位,会大大降低脚本的执行速度。
2、Xpath会随着页面的布局的改变而改变,几乎不能维护
优点
1、可以做布尔逻辑判断,例如//*[@id="kw" and @name="wd"]
2、可以进行模糊定位,contains(),start-with(),ends-with()等
'''
5. 刷新退出等试验
# 刷新页面
driver.refresh()
# 截图
driver.get_screenshot_as_file("res.jpeg")
# 退出
driver.quit()
应用2. 获取博客列表
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from requests_html import HTMLSession
def parse_data(url):
all_parse = HTMLSession().post(url).html.find(".article-item-box")
if not len(all_parse):
raise Exception("End Load!")
return [{"title": item.text.split("\n")[0][2:], "link": item.links.pop()} for item in all_parse]
def get_all_data(url):
suffix = "/article/list/{}"
all_data = list()
try:
index = 1
while True:
this_data = parse_data(url + suffix.format(index))
print(index)
all_data.extend(this_data)
index += 1
except Exception as e:
print(e)
return all_data
PRE_HTML = "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>个人博客</title></head><body>"
SUF_HTML = "</body></html>"
all_data = get_all_data(url)
print(len(all_data))
# 创建html头
with open("my_blog.html", "w", encoding="utf-8") as code:
code.write(PRE_HTML)
for data in all_data:
with open("my_blog.html", "a", encoding="utf-8") as code:
code.write("<div><a class='blog' target='_blank' href='{}'>{}</a></div>".format(data.get("link"), data.get("title")))
with open("my_blog.html", "a", encoding="utf-8") as code:
code.write(SUF_HTML)
import os
os.system("my_blog.html") # 使用系统命令打开该文件, 默认使用浏览器打开