爬虫之selenium

2020-03-19 15:43:19 浏览数 (1)

目录

  • xpath选择器
  • 二、css选择器
  • 三、selenium模块的使用
    • 3.1elenium介绍
    • 3.2模块的使用
  • 四、动作链
  • 五、爬取京东商品信息
  • 六、12306自动登录
  • 七、cookie池
  • 八、fiddler抓包工具的简单使用

xpath选择器

代码语言:javascript复制
#xpath:xml查找语言,在xml中查找标签的语言
#/从节点中选取和//
/body/p   直接子节点
/body//p 子子孙孙
代码语言:javascript复制
# xpath选择
# lxml解析库中的xpath讲解
from lxml import etree
doc='''
<html>
 <head>
  <base href='http://example.com/' />
  <title>Example website</title>
 </head>
 <body>
  <div id='images'>
   <a href='image1.html' id='id_1'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>
   <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
   <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
   <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
   <a href='image5.html' class='li li-item' name='items'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
   <a href='image6.html' name='items'><span><h5>test</h5></span>Name: My image 6 <br /><img src='image6_thumb.jpg' /></a>
  </div>
 </body>
</html>
'''
# 实例化的第一种方式(字符串)
html=etree.HTML(doc)
# 第二种方式(文件)
# html=etree.parse('search.html',etree.HTMLParser())
#  基本使用   (****重点,xpath选择出来的结果都是列表)
# ret=html.xpath('//body/div/a')
# 取文本,取属性
# 取属性
# ret=html.xpath('//body/div/a/@href')
#取文本
# ret=html.xpath('//body/div/a/text()')

xpath标签选择
####------
#所有标签
# a=html.xpath('//*')

# 2 指定节点(结果为列表)
# a=html.xpath('//head')

# 3 子节点,子孙节点
# a=html.xpath('//div/a')
# a=html.xpath('//body/a') #无数据
# a=html.xpath('//body//a')

# 4 父节点
#  a[@href="image1.html"] 找a标签,a标签的href属性是image1.html
# find(name='a',href='image1.html')
# a=html.xpath('//body//a[@href="image1.html"]/..')
# a[1] body下的第一个a
# a=html.xpath('//body//a[1]/..')
# 也可以这样(了解)
# a=html.xpath('//body//a[1]/parent::*')

# 5 属性匹配
# a=html.xpath('//body//a[@href="image2.html"]/text()')
# a=html.xpath('//body//a[@href="image2.html"]')

# 6 文本获取
# a=html.xpath('//body//a[@href="image1.html"]/text()')

# 7 属性获取
# a=html.xpath('//body//a/@href')
# # 注意从1 开始取(不是从0)
# a=html.xpath('//body//a[1]/@href')
# 选最后一个
# a=html.xpath('//body//a[last()]/@href')

# 8 属性多值匹配
#  a 标签有多个class类,直接匹配就不可以了,需要用contains
# a=html.xpath('//body//a[@class="li"]')
# a=html.xpath('//body//a[contains(@class,"li")]')
# a=html.xpath('//body//a[contains(@class,"li")]/text()')

# 9 多属性匹配
# a=html.xpath('//body//a[contains(@class,"li") or @name="items"]')
# a=html.xpath('//body//a[contains(@class,"li") or @name="items"]/text()')
# a=html.xpath('//body//a[contains(@class,"li") and @name="items"]/text()')
# a=html.xpath('//body//a[contains(@class,"li")]/text()')

# 10 按序选择
# a=html.xpath('//a[2]/text()')
# a=html.xpath('//a[2]/@href')
# 取最后一个
# a=html.xpath('//a[last()]/@href')
# 位置小于3的
# a=html.xpath('//a[position()<3]/@href')
# 倒数第二个
# a=html.xpath('//a[last()-2]/@href')

# 11 节点轴选择
# ancestor:祖先节点
# 使用了* 获取所有祖先节点
# a=html.xpath('//a/ancestor::*')
# # 获取祖先节点中的div
# a=html.xpath('//a/ancestor::div')
# attribute:属性值
# a=html.xpath('//a[1]/attribute::*')
# child:直接子节点
# a=html.xpath('//a[1]/child::*')
# descendant:所有子孙节点
# a=html.xpath('//a[6]/descendant::*')
# following:当前节点之后所有节点
# a=html.xpath('//a[1]/following::*')
# a=html.xpath('//a[1]/following::*[1]/@href')
# following-sibling:当前节点之后同级节点
# a=html.xpath('//a[1]/following-sibling::*')
# a=html.xpath('//a[1]/following-sibling::a')
# a=html.xpath('//a[1]/following-sibling::*[2]/text()')
# a=html.xpath('//a[1]/following-sibling::*[2]/@href')
# print(a)

# //*[@id="key"]
#//*[@id="settleup"]/div[1]
#/html/body/div[1]/div[4]/div/div[2]/div/div[3]/div[1]

##settleup > div.cw-icon

css选择器和xpath选择器都可以直接在浏览器中copy

二、css选择器

关于css选择器在前端部分已经做了详细的介绍,请参考文章。

三、selenium模块的使用

3.1elenium介绍

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器 有了selenium能够实现可见即可爬 -使用(本质,并不是python在操作浏览器,而是python在操作浏览器驱动(xx.exe),浏览器驱动来驱动浏览器) -0 以驱动谷歌浏览器为例子(建议你用谷歌,最合适)找谷歌浏览器驱动 -0 如果是windows,解压之后是个exe,不同平台就是不同平台的可执行文件 -1 安装模块:pip3 install selenium -2 需要浏览器驱动(ie,火狐,谷歌浏览器。。。。驱动得匹配(浏览器匹配,浏览器版本跟驱动匹配)) -3 写代码

3.2模块的使用

代码语言:javascript复制
-selenium的使用
  1 实例化 bro=webdriver.Chrome(executable_path='./chromedriver')
  2 发送请求 bro.get('https://www.baidu.com/')
  3 打印加载完成的(js执行完成)html,bro.page_source
  4 找控件(自己的一堆方法,css,xpath)
  5 向控件中写数据  send_keys('')
  6 点击控件  click
  7 清空控件 clear
  8 显式等待和隐式等待(都用隐士:bro.implicitly_wait(10))
    显示等待:WebDriverWait()详细介绍访问链接:https://blog.csdn.net/sinat_41774836/article/details/88965281
  9 获取cookie      bro.get_cookies()
  10 补充:find_elements_xxx和find_element_xx 一个是找所有,一个是找到第一个
  
-其他操作
    -模拟浏览器前进后退 bro.back()  bro.forword()
    
-选项卡管理,用的是执行js
import time
from selenium import webdriver

browser=webdriver.Chrome()
browser.get('https://www.baidu.com')
browser.execute_script('window.open()')

print(browser.window_handles) #获取所有的选项卡
browser.switch_to_window(browser.window_handles[1])
browser.get('https://www.taobao.com')
time.sleep(10)
browser.switch_to_window(browser.window_handles[0])
browser.get('https://www.sina.com.cn')
browser.close()
-异常处理,在finally中关闭浏览器(不管是否发生异常都关闭)
-补充:滑动浏览器(执行js)window.scrollTo(0,document.body.scrollHeight)
browser.execute_script(window.scrollTo(0,document.body.scrollHeight)
-动作链和截图和切换frame(了解)

四、动作链

代码语言:javascript复制
#使用动作链
# 使用动作链
#1 得到一个动作练对象
action=ActionChains(bro)
# 使用动作链
#2 点击并且夯住
action.click_and_hold(div)
#3 移动x坐标,y坐标
for i in range(5):
    action.move_by_offset(10,10)
# 直接把上面的div移动到某个元素上
# action.move_to_element(元素控件)
# 直接把上面的div移动到某个元素上的某个位置
# action.move_to_element_with_offset()

#4 调用它,会动起来
action.perform()
time.sleep(1)
#5 释放动作链
action.release()

五、爬取京东商品信息

实现的功能:打开浏览器、进入京东、输入文字回车进行搜索、分页爬取搜索后得到的信息

代码语言:javascript复制
#爬取京东商品链接,名称,价格,评论数,图片

#爬取京东商品信息

from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys
#键盘按键操作
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import StaleElementReferenceException
from selenium.webdriver.support import expected_conditions as EC
#用于判断动态元素是否存在


bro = webdriver.Chrome(executable_path='./chromedriver')
bro.get('https://www.jd.com/')
bro.implicitly_wait(10)#等待10秒用于加载缓存
wait = WebDriverWait(bro,10)
input_search = bro.find_element_by_id('key')
input_search.send_keys('macpro')
input_search.send_keys(Keys.ENTER)

def get_goods(bro):
    li_list = bro.find_elements_by_class_name('gl-item')
    # li_list.find_element_by_css_selector()
    # print(li_list)

    for li in li_list:
        img_url = li.find_element_by_css_selector('.p-img img').get_attribute('src')  # 选取.p-img下面的img标签
        if not img_url:
            img_url = 'https:'   li.find_element_by_css_selector('.p-img img').get_attribute('data-lazy-img')

        good_name = li.find_element_by_css_selector('.p-name>a').get_attribute('title')
        print('商品名:',good_name)
        print(img_url)
        good_price = li.find_element_by_css_selector('.p-price i').text
        print('商品价格',good_price)
        commit = li.find_element_by_css_selector('.p-commit a').text
        print(commit)
    for i in range(3):
        try:
            next_page = wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'pn-next')))
            next_page.click()
            time.sleep(2)
            print('下一页')
            break
        except StaleElementReferenceException:
            time.sleep(0.5)
            print('try to find element click')
            continue
    # time.sleep(0.1)

    get_goods(bro)

get_goods(bro)

#关闭浏览器
finally:
    bro.close()

六、12306自动登录

代码语言:javascript复制
# 自动登录12306
# pip3 install pillow
from PIL import Image
from chaojiying import Chaojiying_Client
from selenium import webdriver
from selenium.webdriver import ActionChains
import time
import json
import requests
bro =webdriver.Chrome(executable_path='./chromedriver')
bro.get('https://img.yuanmabao.com/zijie/pic/2020/03/19/yqkttlhw1gr.html')
tag_code =bro.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img')

# 查看控件的位置和大小
size =tag_code.size
location =tag_code.location
print(size)
print(location)

img_tu = (int(location['x']) ,int(location['y']) ,int(location['x' ]  size['width']) ,int(location['y' ]  size['height']))
# # 抠出验证码
# #打开
img =Image.open('./main.png')
# 抠图
fram =img.crop(img_tu)
# 截出来的小图
fram.save('code.png')

# 调用超级鹰,破解

def get_result():
    chaojiying = Chaojiying_Client('306334678', 'lqz123', '903641')  # 用户中心>>软件ID 生成一个替换 96001
    im = open('code.png', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    print(chaojiying.PostPic(im, 9004)) # 1902 验证码类型  官方网站>>价格体系 3.4 版 print 后要加()
    return chaojiying.PostPic(im, 9004)['pic_str']


# 返回结果如果有多个 260,133|123,233,处理这种格式[[260,133],[123,233]]
result=get_result()
all_list=[]
if '|' in result:
    list_1 = result.split('|')
    count_1 = len(list_1)
    for i in range(count_1):
        xy_list = []
        x = int(list_1[i].split(',')[0])
        y = int(list_1[i].split(',')[1])
        xy_list.append(x)
        xy_list.append(y)
        all_list.append(xy_list)
else:
    x = int(result.split(',')[0])
    y = int(result.split(',')[1])
    xy_list = []
    xy_list.append(x)
    xy_list.append(y)
    all_list.append(xy_list)
print(all_list)

# 用动作链,点击图片
# [[260,133],[123,233]]
for a in all_list:
    x = a[0]
    y = a[1]
    ActionChains(bro).move_to_element_with_offset(tag_code, x, y).click().perform()
    time.sleep(1)
username=bro.find_element_by_id('username')
username.send_keys("你自己的账号")
pwd=bro.find_element_by_id('password')
pwd.send_keys('你自己的密码')
submit=bro.find_element_by_id('loginSub')
submit.click()

#获取cookie
# 使用requests模块,携带cookie朝某个接口发请求

c = bro.get_cookies()
print(c)
with open('xxx.json', 'w') as f:
    json.dump(c, f)
cookies = {}
# 获取cookie中的name和value,转化成requests可以使用的形式
# for cookie in c:
#     cookies[cookie['name']] = cookie['value']
#
# print(cookies)

with open('xxx.json', 'r') as f:
    di = json.load(f)
cookies = {}
# 获取cookie中的name和value,转化成requests可以使用的形式
for cookie in di:
    cookies[cookie['name']] = cookie['value']

print('---------')
print(cookies)
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36',
    'Referer': 'https: // kyfw.12306.cn /otn/view/index.html',
    'Origin': 'https://kyfw.12306.cn',
    'Host': 'kyfw.12306.cn',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',

}
res = requests.post('https://kyfw.12306.cn/otn/index/initMy12306Api',headers=headers,
                    cookies=cookies)
print(res.text)

七、cookie池

代码语言:javascript复制
# 通过selenium登录,获取cookie,放到redis中,用flask框架搭建服务,每发一次请求,获取一个cookie

dic={'k1':'v1','k2':'v2','k3':'v3'}

八、fiddler抓包工具的简单使用

代码语言:javascript复制
# 抓包工具的使用(fiddler,charles)
# # 6 fildder的使用:http://101.133.225.166:8088/
#下载地址:https://www.telerik.com/fiddler
#  https://telerik-fiddler.s3.amazonaws.com/fiddler/FiddlerSetup.exe
# 双击安装,一路下一步
# 桌面上绿色的东西
# 双击打开(中文汉化版)

# 这个东西可以抓手机包,手机app都是http请求,手机端配置代理(装有fildder的机器地址)
手机跟电脑连到同一个路由器,手机端配置代理是你的电脑 

0 人点赞