验证码识别

提取图片人工打码……

第三方验证码识别库

  • pytesseract
  • 百度 OCR
  • 超级鹰

对于请求 登录页面等,会在本地设置 cookie 的链接。可以通过 session = requests.Session(), 创建一个 session 对象(用法 requests 相似)。会自动对返回结果中的 返回头 进行存储,以便于下次请求使用。

ip 代理

服务器可能会通过记录 ip 某一段时间内的访问次数,以此拒绝访问。

可以使用代理服务器减少 单个 ip 的访问次数。突破自身 ip 的访问限制。同时 隐藏自身真实 ip。

代理 ip 相关的网站:

from Package.myrequest import MyRequests

url1 = 'https://www.baidu.com/s?wd=ip'

page_text = MyRequests.get(url1, proxies={"http": '123.55.102.9:9999'}).text

with open('iptest.html', 'w', encoding='utf-8') as fp:
    fp.write(page_text)
# 返回的ip还是本机ip

多任务

并发: 当有多个线程在操作时,如果系统只有一个 cpu 核心,则他根本不可能真正同时进行一个以上线程.他只能将运行时间划分成若干个时间段 再将时间段分给各个线程执行,其他线程处于挂起状态. 这种方式称为 并发(Concurrent)

并行: 当系统有一个以上核心时,则线程的操作有可能实现并发,一个核心执行时,其他核心可以执行另一个线程. 多个线程不抢占 cpu 资源,可以同时进行.成为 并行(Parallel)

实现多任务的方式 : 进程 > 线程 > 协程 ('>' 包含多个)
  • 多进程模式 : (计算密集型操作
  • 多线程模式:线程是最小的执行单元,而进程由至少一个线程组成。(耗时操作,爬虫 IO。
  • -协程(多进程+多线程模式) (耗时操作

如何调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间。


创建进程池

windons 下 使用 multiprocessing 模块中 Process 类创建新进程

主进程执行完毕(子进程是分离出去的),随后子进程也会自动关闭.

couse = Process(target=func, name=进程名,args=(函数需要的参数(元组形式)), 返回创建的子进程进程

子进程对象的调用方法:

  • .start() 启动进程任务
  • .run() 执行任务,但并没有启动进程
  • .terminate() 结束工作进程,不在处理未处理的任务。

如果需要创建多个进程时,可以使用 multiprocessing 中的 Pool 类创建进程池。

初始化 pool 时可以指定一个最大进程数,当有新的请求提交到 pool 中时:

  • 如果池还没有满,就会创建一个新的进程执行该请求。
  • 如果池已满,该请求等待池中有进程结束。才会创建新的进程来执行
  • 分为阻塞式,非阻塞式:

阻塞式:添加一个进程,等进程执行完毕 在添加执行另一个进程.

非阻塞式:全部添加到队列中,立刻返回.并没有等待其他进程完毕. 但是回调函数是等待一个进程完成立即调用

from multiprocessing import Pool

pool = Pool(5)
func = lambda a, b: a + b

# 阻塞式
pool.apply(func, args=('1', '2'))

# 非阻塞式
pool.apply_async(func, args=('1', '2'), callback=lambda val: val)

# 关闭进程池,不再接受新的进程
pool.close()

# 主进程阻塞等待子进程的退出。主进程执行完毕,随后子进程也会马上关闭
pool.join()

创建线程

线程状态: 新建 就绪 运行 阻塞 结束

线程可以共享全局变量

如果多个线程共同对某个数据修改,可能出现数据不同步的问题。

  • 为了保证数据的正确性,需要对多个线程进行同步。
  • 同步:一个一个的完成,一个做完另一个才能进来。

使用 Thread 的 lock 和 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 和 release 方法 .

import threading
from time import sleep

TEMP = 0
lock = threading.Lock()

def task1():
    global TEMP   
    lock.acquire()  # 阻塞. # 获取线程锁    
    sleep(0.5)
    TEMP += 1
    lock.release()  # 关闭锁, 只要不释放其他线程无法进入运行状态

thread = threading.Thread(target=task1)
thread1 = threading.Thread(target=task1)

thread.start() # 启动此线程
thread1.start()

python 内置线程池(用法类似于 内置进程池) from multiprocessing.pool import ThreadPool


创建协程

在执行函数 A 时,可以随时中断,去执行函数 B ,然后中断继续执行函数 A (可以自由切换)。 但这一过程并不是函数调用(没有调用语句),这一整个过程看似像多线程,然而协程只有一个线程执行.

greenlet 可以实现协程,不过每一次都要人为的去指向下一个该执行的协程,显得太过麻烦。

python 还有一个比 greenlet 更强大的并且能够自动切换任务的模块 gevent

gevent 每次遇到 io 操作,需要耗时等待时,会自动跳到下一个协程继续执行

import gevent

gevent.monkey.patch_all() # *1 猴子补丁
func = lambda val: val

threads = [gevent.spawn(func, i) for i in range(10)]

# grevent_obj.join()    # 等待协程结束(主进程不会等待)
gevent.joinall(threads) # 可接多个参数

gevent.sleep() # 模拟一个耗时操作, time.sleep没有让gevent感知到等待

*1 :把标准库中的 thread/socket 等给替换掉.这样我们在后面使用 socket 的时候可以跟平常一样使用,无需修改任何代码,但是它变成非阻塞的了. (将阻塞(等待)的协程自动切换)


爬虫异步的方式

多线程,多进程

优点:可以为相关的阻塞程序单独开启线程或进程,阻塞操作就可以异步执行。

缺点:无法无限制的开启多线程或者多进程。

未完......


相关推荐:

来自系列:Python 爬虫学习笔记

分类 python下文章:

1.0 爬虫的介绍,和requests模块的简单使用

1.1 数据解析的三种方式。正则表达式, bs4, xpath

2.0.1 协程的 async/await 实现 爬虫 单线程 + 异步协程的实现

3.0 基于selenium 模块的 爬虫操作。 selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。

更多...

评论([[comments.sum]])

发表

加载更多([[item.son.length-2]])...

发表

2020-11 By chuan.

Python-flask & bootstrap-flask

图片外链来自:fghrsh

互联网ICP备案号:蜀ICP备2020031846号