python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用

一丶单线程+多任务的异步协程

特殊函数

# 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数

async def get_request(url):
print('正在请求~~', url)
await asyncio.sleep(2)
print('请求结束!!', url)

协程对象

#  - 对象: 特殊函数被调用后,函数内部的实现语句不会被立即执行,然后该函数调用会返回一个协程对象。
# - 结论: 协程对象==特殊的函数调用 ### c 是 协程对象
# 函数调用: 返回的是一个协程对象
c = get_request(url) # <generator object get_request at 0x000001C626DCF048

任务对象

# 任务对象
- 1.起始就是对协程对象的进一步封装。
- 2.结论:任务对象==高级的协程对象==特殊的函数调用
- 3.绑定回调:
- 回调函数什么时候被执行?
- 任务对象执行结束后执行回调函数
- task.add_done_callback(func)
- func必须要有一个参数,该参数表示的是该回调函数对应的任务对象
- 回调函数的参数.result():任务对象对应特殊函数内部的返回值 ### 任务对象
task = asyncio.ensure_future(c) ### 绑定回调函数 parase ,传入函数名即可
task.add_done_callback(parase)

事件循环对象

# 事件循环对象
- 作用:将其内部注册的任务对象进行异步执行。 ### 创建一个事件循环对象
loop = asyncio.get_event_loop()
# 循环执行 , 将任务对象注册到事件循环对象中并且开启事件循环
loop.run_until_complete(asyncio.wait(tasks_list))

编码流程

# 编码流程

    - 定义特殊函数
- 创建协程对象
- 封装任务对象
- 创建事件循环对象
- 将任务对象注册到事件循环中且开启事件循环对象

注意事项***

- 注意:在特殊函数内部的实现语句中不可以出现不支持异步的模块对应的代码,否则
就是终止多任务异步协程的异步效果 - 注意重点:requests模块不支持异步,在多任务的异步协程中不可以使用requests

aiohttp模块的使用

- 概念:支持异步的网络请求模块
- 编码流程:
- 写基本架构:
with aiohttp.ClientSession() as s:
with s.get(url) as response:
page_text = response.text()
return page_text
- 补充细节:
- 添加async关键字
- 每一个with前加上async
- 添加await关键字
- 加载每一步的阻塞操作前加上await
- 请求
- 获取响应数据 # -*-coding:utf-8-*-
# Author:Ds
'''
多任务的异步爬虫
'''
import asyncio
import time
# aiohttp 异步网络请求模块
import aiohttp from lxml import etree async def get_request(url):
# 开启一个连接请求
async with aiohttp.ClientSession() as s:
# 发送一个连接请求
async with s.get(url=url) as response:
# await 的使用情况:
# 请求和响应都存在网络传输,
page_text =await response.text()
return page_text def parase(task):
'''
# 解析page_text
:param task:
:return:
''' # 获取 执行函数调用的结果
page_text=task.result() # 实例化etree解析对象
tree=etree.HTML(page_text)
page_data=tree.xpath('//*[@id="page"]/a[1]/span[1]/i/@class')[0]
print(page_data) urls = [
'http://127.0.0.1:5000/ip01',
'http://127.0.0.1:5000/ip02',
'http://127.0.0.1:5000/ip01',
'http://127.0.0.1:5000/ip02',
'http://127.0.0.1:5000/ip01',
'http://127.0.0.1:5000/ip02', ] start_time = time.time() # 列表 协程对象列表
coroutine_list = []
# 列表 任务对象列表
tasks_list = []
for url in urls:
### c 是 协程对象
# 函数调用: 返回的是一个协程对象
c = get_request(url) # <generator object get_request at 0x000001C626DCF048 ### 任务对象
task = asyncio.ensure_future(c)
### 绑定回调函数
task.add_done_callback(parase)
tasks_list.append(task)
coroutine_list.append(c) # print(coroutine_list)
# print(tasks_list) ### 创建一个事件循环对象
loop = asyncio.get_event_loop()
# 循环执行 , 将任务对象注册到事件循环对象中并且开启事件循环
loop.run_until_complete(asyncio.wait(tasks_list)) print('总耗时:', time.time() - start_time)
loop.close()

二丶selenium模块

概述

    - 概念:基于浏览器自动化的一个模块。
- Appium是基于手机的自动化的模块。
- selenium和爬虫之间的关联
- 便捷的爬取到动态加载的数据
- 可见即可得
- 便捷的实现模拟登陆

基本使用

    - 基本使用:
- 环境安装
- pip install selenium
- 下载浏览器的驱动程序
- http://chromedriver.storage.googleapis.com/index.html
- 浏览器版本和驱动程序的映射关系:
https://blog.csdn.net/huilan_same/article/details/51896672

捕获动态数据

# -*-coding:utf-8-*-
# Author:Ds from selenium import webdriver
import time
from lxml import etree options=webdriver.ChromeOptions()
options.binary_location = r"E:\Program Files (x86)\Google\Chrome\Application\chrome.exe" browser=webdriver.Chrome('chromedriver.exe',options=options)
url='https://www.fjggfw.gov.cn/Website/JYXXNew.aspx'
browser.get(url)
time.sleep(1) # page_source : 获取页面资源 所有数据
page_text=browser.page_source # 列表存储页面源码数据
all_page_text=[] for i in range(3):
next_page_btn=browser.find_element_by_xpath('//*[@id="kkpager"]/div[1]/span[1]/a[7]')
next_page_btn.click()
time.sleep(1)
# 往列表里添加一整页数据
all_page_text.append(browser.page_source) for page_text in all_page_text:
tree=etree.HTML(page_text)
# 获取页面指定动态数据的第一条数据
title=tree.xpath('//*[@id="list"]/div[1]/div/h4/a/text()')[0]
print(title)

动作链

- 动作链
- 在使用find系列的函数进行标签定位的时候如果出现了NoSuchElementException如何处理?
- 如果定位的标签是存在于iframe标签之下的,则在进行指定标签定位的时候
必须使用switch_to.frame()的操作才可。
# -*-coding:utf-8-*-
# Author:Ds
from selenium import webdriver
import time
from lxml import etree options=webdriver.ChromeOptions()
options.binary_location = r"E:\Program Files (x86)\Google\Chrome\Application\chrome.exe" browser=webdriver.Chrome('chromedriver.exe',options=options) browser.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable') time.sleep(1) # 传入iframe的ID #frame的参数为iframe标签的id属性值
browser.switch_to.frame('iframeResult')
# 找到要执行动作的标签元素
div_tag=browser.find_element_by_id('draggable') # 实例化一个动作链对象, 传入浏览器对象
action=webdriver.ActionChains(browser)
action.click_and_hold((div_tag)) for i in range(3):
# 执行动作链 , perform() 表示立即执行
action.move_by_offset(5,0).perform()
time.sleep(0.1) browser.quit()

无头浏览器

- 无头浏览器
- phantomjs
- 谷歌无头浏览器(推荐)
# -*-coding:utf-8-*-
# Author:Ds
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
import time
from lxml import etree # 设置浏览器无头信息
chrome_options=Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.binary_location=r"E:\Program Files (x86)\Google\Chrome\Application\chrome.exe" browser=webdriver.Chrome('chromedriver.exe',chrome_options=chrome_options) browser.get('https://www.taobao.com') # 截图保存
browser.save_screenshot('./taobao_index.png')
print(browser.page_source)

如何规避selenium被监测到的风险

- 如何规避selenium被监测到的风险
- 网站可以根据:'window.navigator.webdriver' 的返回值鉴定是否使用了selenium
- undefind:正常
- true:selenium
# -*-coding:utf-8-*-
# Author:Ds
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
import time
from lxml import etree # 设置浏览器无头信息
chrome_options=Options()
chrome_options.binary_location=r"E:\Program Files (x86)\Google\Chrome\Application\chrome.exe" ### 设置 不被监测
# console输入: 'window.navigator.webdriver' 为true则检查出是使用的 selenium .
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation']) browser=webdriver.Chrome('chromedriver.exe',chrome_options=chrome_options) browser.get('https://www.taobao.com')

三丶12306的模拟登录

# -*-coding:utf-8-*-
# Author:Ds
# 打码平台
from CJY import Chaojiying_Client
# 自动化工具
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver import ActionChains
import time headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
} # 处理图片模块
from PIL import Image # 处理图片验证码
def transform(imgPath,imgType):
chaojiying=Chaojiying_Client('打码平台用户','打码平台密码','901821')
# chaojiying2=Chaojiying_Client('bobo328410948', 'bobo328410948', '899370')
img=open(imgPath,'rb').read()
return chaojiying.PostPic(img,imgType)['pic_str'] # 自动化工具设置
chrome_options=Options()
chrome_options.binary_location=r"E:\Program Files (x86)\Google\Chrome\Application\chrome.exe" # 生成浏览器对象
browser=webdriver.Chrome('chromedriver.exe',chrome_options=chrome_options) # 发送请求
browser.get('https://kyfw.12306.cn/otn/login/init')
time.sleep(3) # 截取 整张12306的页面
browser.save_screenshot('main.png') # 在main.png 中 截取下载验证码
img_tag=browser.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img') # 获取 验证码图片的位置和大小
location=img_tag.location # 最左下角位置(x,y)
size=img_tag.size # img标签对应的图片大小
print(location,size) # 裁剪范围
rangle=(int(location['x']),int(location['y']),int(location['x'])+size['width'],int(location['y'])+size['height'])
print(rangle) # 左下坐标 和 右上坐标 # 裁取验证码
i=Image.open('./main.png')
frame=i.crop(rangle)
frame.save('./code.png') # 解析验证码中的内容 , 获得坐标
result=transform('./code.png',9004)
print(result)
time.sleep(2)
# 260,140|260,139 ==> [[260,140],[260,139]]
# 构建数据 '266,77|263,168|199,147'
# all_list=[[x] for x in result.split('|')]
# print(all_list)
all_list=[]
for el in result.split('|'):
x,y=el.split(',')
all_list.append([int(x),int(y)])
print(all_list) # 循环 打码平台识别出的图片坐标
for x,y in all_list:
# 执行点击动作链
ActionChains(browser).move_to_element_with_offset(img_tag,x,y).click().perform()
time.sleep(0.5) # 填写用户名
username=browser.find_element_by_xpath('//*[@id="username"]')
username.send_keys('XXXX')
# 填写用户密码
password=browser.find_element_by_xpath('//*[@id="password"]')
password.send_keys('XXXX') time.sleep(1) # 点击登录
login_btn=browser.find_element_by_xpath('//*[@id="loginSub"]')
login_btn.click() # 获取页面资源,保存到本地
page_text=browser.page_source
with open('./traintest.html','w' ,encoding='utf-8') as f:
f.write(page_text)
time.sleep(8) # 释放浏览器对象资源
browser.quit()

python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用的更多相关文章

  1. asyncio模块实现单线程-多任务的异步协程

    本篇介绍基于asyncio模块,实现单线程-多任务的异步协程 基本概念 协程函数 协程函数: 定义形式为 async def 的函数; aysnc 在Python3.5+版本新增了aysnc和awai ...

  2. 【Python3爬虫】使用异步协程编写爬虫

    一.基本概念 进程:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动.进程是操作系统动态执行的基本单元. 线程:一个进程中包含若干线程,当然至少有一个线程,线程可以利用进程所拥有的资源.线程 ...

  3. Python用yield form 实现异步协程爬虫

    很古老的用法了,现在大多用的aiohttp库实现,这篇记录仅仅用做个人的协程底层实现的学习. 争取用看得懂的字来描述问题. 1.什么是yield 如果还没有怎么用过的话,直接把yield看做成一种特殊 ...

  4. Python核心框架tornado的异步协程的2种方式

    什么是异步? 含义 :双方不需要共同的时钟,也就是接收方不知道发送方什么时候发送,所以在发送的信息中就要有提示接收方开始接收的信息,如开始位,同时在结束时有停止位 现象:没有共同的时钟,不考虑顺序来了 ...

  5. 小爬爬4.协程基本用法&&多任务异步协程爬虫示例(大数据量)

    1.测试学习 (2)单线程: from time import sleep import time def request(url): print('正在请求:',url) sleep() print ...

  6. 爬虫必知必会(4)_异步协程-selenium_模拟登陆

    一.单线程+多任务异步协程(推荐) 协程:对象.可以把协程当做是一个特殊的函数.如果一个函数的定义被async关键字所修饰.该特殊的函数被调用后函数内部的程序语句不会被立即执行,而是会返回一个协程对象 ...

  7. python爬虫--多任务异步协程, 快点,在快点......

    多任务异步协程asyncio 特殊函数: - 就是async关键字修饰的一个函数的定义 - 特殊之处: - 特殊函数被调用后会返回一个协程对象 - 特殊函数调用后内部的程序语句没有被立即执行 - 协程 ...

  8. Python爬虫进阶 | 异步协程

    一.背景 之前爬虫使用的是requests+多线程/多进程,后来随着前几天的深入了解,才发现,对于爬虫来说,真正的瓶颈并不是CPU的处理速度,而是对于网页抓取时候的往返时间,因为如果采用request ...

  9. Python中异步协程的使用方法介绍

    1. 前言 在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后 ...

随机推荐

  1. 2. 代理模式(C++)

    1.介绍 代理模式:为其他对象提供一种代理以控制对这个对象的访问.这样实现了业务和核心功能分离. 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口.在某些情况下,一个对象不适合或者不能 ...

  2. 10-赵志勇机器学习-meanshift

    (草稿) meanshift 也是一种聚类方法. 优点在于:不需要提前指定类型数. 缺点就是计算量大 过程:(最一般的做法,没有使用核函数) 1. 逐点迭代,设置为位置中心 2. 计算所有点到位置中心 ...

  3. 09-numpy-笔记-repeat

    repeat:复制元素 axis = 0 复制每行 axis = 1 复制每列 2 表示复制一遍 不设置axis,复制每个,按行展开成一行. >>> import numpy as ...

  4. VS Code配置Python

    安装 1.安装python插件 直接在VS Code里搜索“Python”插件,安装. 2.下载Python 去官网下载Python 其他的插件在第一次运行Python程序会提示,按要求安装即可. 运 ...

  5. 关于System.FormatException异常

    什么是FormatException 参数格式无效或复合格式字符串不正确时引发的异常. 继承 Object Exception SystemException FormatException 详细说明 ...

  6. 复旦大学2018--2019学年第二学期高等代数II期末考试情况分析

    一.期末考试成绩班级前十名 丁思成(99).周烁星(97).王捷翔(96).顾文颢(92).顾天翊(90).封清(89).张思哲(89).李哲蔚(88).陈钦品(88).邹年轶(88).王祝斌(88) ...

  7. PID optimizer

    如何评价PID optimizer? 论文链接:http://www4.comp.polyu.edu.hk/~cslzhang/paper/CVPR18_PID.pdf作者github:https:/ ...

  8. Spring Boot 知识笔记(servlet、监听器、拦截器)

    一.通过注解自定义servlet package net.Eleven.demo.servlet; import javax.servlet.ServletException; import java ...

  9. Hbase安装使用

    启动Hadoop 启动Hbase jps 进入shell 建立表及使用

  10. Error Code: 1175. You are using safe update

    使用MySQL执行update的时候报错:Error Code: 1175. You are using safe update mode and you tried to update a tabl ...