这是我编写的一个异爬虫基类,有以下几点优点
使用接口继承的思想
继承Crawler类后,必须实现parse
和handle
方法,否则程序报错,虽然Python没有接口的特性,但是使用raise
方法抛出了未实现接口的异常。
类型注释
每一个方法的形式参数都加入注释,使得IDE能够识别类型。
开发哲学
- 简单优雅于复杂
- 标准库优雅于三方库。
- 标准函数优雅于自己写函数。
- 专业的函数处理专业的事情。
- 代码规范很重要。
- 代码注释很重要
from typing import List
from urllib.parse import urlparse
import asyncio
import aiohttp
def save(content: any, filename: str, mode='a', encoding='utf-8', end='\n'):
with open(filename, mode=mode, encoding=encoding) as file:
if type(content) == str:
file.write(content + end)
else:
file.write(content)
print(f'The file is saved "{filename}" successfully!')
class Crawler(object):
"""
爬虫基类,所有爬虫都应该继承此类
"""
def __init__(self, start_url: List[str]) -> None:
"""
初始化
:param start_url: 爬虫起始列表
:param start_url: 爬虫起始列表
:param domain: 域名
"""
self.items = None
self.name = 'myspider'
self.start_url = start_url
self.domain = '{uri.scheme}://{uri.netloc}'.format(uri=urlparse(self.start_url[0]))
async def parse(self, response):
"""
从response中解析出所有目录的URL链接
"""
raise NotImplementedError
async def request(self, url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
response = await self.parse(await resp.text())
url_object = urlparse(url)
return dict(response=response, url=url) # 有返回值
async def run(self):
tasks = [asyncio.ensure_future(self.request(i)) for i in self.start_url]
await asyncio.wait(tasks)
results = await asyncio.gather(*tasks) # 获取返回值
# self.items = results
self.handle(results)
print("任务完成...")
def handle(self, items):
for item in items:
save(item.text(), "test.txt")
raise NotImplementedError
标签:异步,url,self,爬虫,start,基类,async,def
From: https://www.cnblogs.com/huanghongzhe/p/16792037.html