0
点赞
收藏
分享

微信扫一扫

爬虫1-selenium

小飞侠熙熙 2022-11-27 阅读 88


文章目录

  • ​​一.使用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调用打开浏览器, 这就需要驱动器了


爬虫1-selenium_html

  • 安装三大浏览器驱动driver

注意:下载解压后,将​​geckodriver.exe​​复制到Python的安装目录,如下图 。

然后再将Python和火狐浏览器安装目录添加到系统环境变量的Path下面。

爬虫1-selenium_css_02


爬虫1-selenium_json_03

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就是独一无二的定位

爬虫1-selenium_css_04

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()

爬虫1-selenium_css_05


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.浏览博客第一条

爬虫1-selenium_json_06

# 绝对路径定位 存在很大的问题就是如果页面元素一改变元素的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") # 使用系统命令打开该文件, 默认使用浏览器打开


举报

相关推荐

0 条评论