爬虫多场景通用请求方法封装(同步,异步)

2024-02-03 12:32:00 浏览数 (1)

一. 同步

  • 阻塞模式:同步爬虫是一种阻塞式的爬取方式,即程序在发送一个请求后,会一直等待服务器的响应,直到响应返回为止。在这个等待期间,程序无法执行其他任务,会被阻塞。
  • 适用场景: 适用于简单的爬取任务,不需要大量并发请求的场景。当爬取速度不是主要问题时,同步爬虫通常更易于实现和调试。
代码语言:javascript复制
import requests, urllib

class Requestsutils:    
    def __init__(self, ip:str=None, enableProxy:bool=False) -> None:
        proxy = f"http://{ip}"
        self.proxies = {"http": proxy,"https": proxy} if enableProxy else urllib.request.getproxies()
    
     
    def send_requsest(self, method:str, url:str, **kwargs):
        return requests.request(method, url, 
                                    **kwargs,
                                    proxies=self.proxies
                                    )

该方法主要针对本地电脑开启代理后需要手动设置代理ip的通点。如果需要设置远程代理则在实例化对象传入远程ip 端口然后将enableProxy设置为True即可。

二. 异步

  • 非阻塞模式: 异步爬虫采用非阻塞的方式发送请求,即程序在发送请求后不会等待响应,而是继续执行后续任务。当有响应返回时,再处理返回的数据。这样可以在等待响应的过程中执行其他任务,提高了效率。
  • 适用场景: 适用于需要大量并发请求的场景,例如同时爬取多个网页或处理大量的I/O操作(如下载文件、访问数据库等)。异步爬虫通常能够更高效地利用网络资源。
代码语言:javascript复制
import aiohttp

from functools import wraps
from asyncio.proactor_events import _ProactorBasePipeTransport

def silence_event_loop_closed(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        try:
            return func(self, *args, **kwargs)
        except RuntimeError as e:
            if str(e) != 'Event loop is closed':
                raise
    return wrapper
_ProactorBasePipeTransport.__del__ = silence_event_loop_closed(_ProactorBasePipeTransport.__del__)
        
class AioHttpClient:
    def __init__(self, ip:str=None, enableProxy:bool=False) -> None:
        self.session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False), trust_env=True)
        self.proxy = f"http://{ip}"
        self.enableProxy = enableProxy
            
    async def send_request(self, method, url, **kwargs):
        return await self.session.request(method, url, proxy=self.proxy if self.enableProxy else None, **kwargs)
        
    async def close_session(self):
        await self.session.close()

调用方式

代码语言:javascript复制
import asyncio
async def main():
    client = AioHttpClient()
    data = await client.send_request("GET", url)
    await client.close_session()
    print(await data.text())

if __name__ == "__main__":
    # 同步
    url = "http://tanblog.cc"
    print(Requestsutils().send_requsest("GET", url).text)
    # 异步
    asyncio.run(main())

0 人点赞