aiohttp爬虫的模板,类的形式
import asyncio
import aiohttp
import async_timeout
from lxml import html
from timeit import default_timer as timer from db import DBData class Crawler:
def __init__(self, **kwargs):
self.domains = kwargs["domains"]
self.max_depth = kwargs["max_depth"]
self.max_retries = 3
self.max_workers = 10
self.Q = asyncio.Queue()
self.db_Q = asyncio.Queue()
self.cache = set()
self.count = 0
self.loop = asyncio.get_event_loop()
self.db_data = DBData() # Clear
self.db_data.clear_crawler() async def get(self, url, timeout):
with async_timeout.timeout(timeout):
async with self.session.get(url) as response:
return await response.text() async def extract_urls(self, url, timeout=10):
tree = html.fromstring(await self.get(url, timeout))
# Search only in domains
return {p for p in tree.xpath("//a/@href")}
# if any(domain in p for domain in self.domains)} async def worker(self):
while True:
url, depth, retries = await self.Q.get()
if url in self.cache:
self.db_Q.put_nowait(url)
self.Q.task_done()
continue
try:
new_urls = await self.extract_urls(url)
except Exception as e:
if retries <= self.max_retries:
self.Q.put_nowait((url, depth, retries + 1))
else:
print("Error in %s: %s" % (url, repr(e)))
else:
self.cache.add(url)
self.count += 1
self.db_Q.put_nowait(url)
print("Depth: %s Retry: %s Visited: %s" % (depth, retries, url))
if depth+1 <= self.max_depth:
for x in new_urls:
self.Q.put_nowait((x, depth + 1, retries))
self.Q.task_done() async def run(self):
async with aiohttp.ClientSession(loop=self.loop) as session:
self.session = session
workers = [self.worker() for _ in range(self.max_workers)]
workers += [self.write_to_db() for _ in range(self.max_workers)]
tasks = [self.loop.create_task(x) for x in workers]
await asyncio.sleep(5)
await self.Q.join()
await self.db_Q.join()
for task in tasks:
task.cancel() def start(self):
for domain in self.domains:
print("Crawling %s start..." % domain) self.Q.put_nowait((domain, 0, 0))
start_time = timer()
self.loop.run_until_complete(asyncio.gather(self.run()))
self.loop.close()
runtime = timer() - start_time print("Crawling %s end. Exec time: %s. Requests: %s" % (
domain, runtime, self.count)) async def write_to_db(self):
while True:
address = await self.db_Q.get()
if await self.db_data.check_url(address) is None:
self.db_data.add_url(address)
print("Write to DB: %s" % address)
self.db_Q.task_done() if __name__ == "__main__":
options = {
"domains": ["https://www.yahoo.com/news/"],
"max_depth": 1
}
c = Crawler(**options)
c.start()
aiohttp爬虫的模板,类的形式的更多相关文章
- C++模板类的使用
1.定义模板类 通过类似于下面的语法可以定义一个模板类: template<typename T> class Job : public virtual RefBase { public: ...
- C++:类模板与模板类
6.3 类模板和模板类 所谓类模板,实际上是建立一个通用类,其数据成员.成员函数的返回值类型和形参类型不具体指定,用一个虚拟的类型来代表.使用类模板定义对象时,系统会实参的类型来取代类模板中虚拟类型从 ...
- C++ 模板类解析
具体模板类作用这边就不细说了,下面主要是描述下模板类的使用方法以及注意的一些东西. #include <iostream> using namespace std; template &l ...
- 使用模板类导致error LNK2019: 无法解析的外部符号
原地址 1.定义模板类: template<class T> class Stack {....}; 2.定义模板成员函数: 每个函数头都要以相同的模板声明打头,并将类限定符改成:类名&l ...
- 开涛spring3(7.2) - 对JDBC的支持 之 7.2 JDBC模板类
7.2 JDBC模板类 7.2.1 概述 Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDB ...
- 7.2 C++模板类实例化
参考:http://www.weixueyuan.net/view/6399.html 总结: array < int >表明用int类型来代替模板类中的类参数“T”,编译器会将模板类ar ...
- [C++]模板类和模板函数
参考: C++ 中模板使用详解 C++模板详解 概念 为了避免因重载函数定义不全面而带来的调用错误,引入了模板机制 定义 模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模 ...
- (转)JDBC模板类。
Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDBC模板类是第一种工作模式. JdbcTempl ...
- spring3:对JDBC的支持 之 JDBC模板类
7.2 JDBC模板类 7.2.1 概述 Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDB ...
随机推荐
- asp.net mvc4 小问题
最近在学习mvc4中间出现一些问题.留作记录.. 1.新建立的项目在vs2013中运行后会出现一个长轮询..这个叫browserLink 是vs2013中新加入的东西.至于更多解释.直接百度.. 关闭 ...
- c# datarow[] 转换成 datatable, List<T> 转datatable
c# datarow[] 转换成 datatable, List<T> 转datatable DdataRow[]转成Datatable private DataTable ToDat ...
- 如何提高Ajax性能
1.适当使用缓存机制 2.使用CDN内容分发来访问Jquery脚本: (1)自己公司架设CDN服务器 (2)使用第三方公司的,比如微软,谷歌等公司的CDN,但有时候不太靠谱 3.JS/CSS文件的打包 ...
- javascript进行百度换肤 和显示隐藏一个窗口的操作
简单的运用javascript来进行百度换肤的操作 <!DOCTYPE html> <html lang="en"> <head> <me ...
- RESTful的理解与设计【PHP】
RESTful 就是一种软件架构的风格,以资源为中心定位,运用http的请求方式(动词)来划定操作.这样的设定优点简单易理解,方便人员对接,形成规范. 资源作为唯一标识,使用相关动词取获取操作.举例, ...
- Matlab基础 数组
一.引用 数组元素引用,下标从1开始 如y(3)表示第3个元素 二.扩充 扩充2*3矩阵为3*3矩阵,并且给a(3,3)赋值为9 三.提取 数组按列存储 全下标变化为单下标: sub2ind((m,n ...
- 转贴:如何学好C++语言.docx
不知道哪里转的.呵呵 抱歉 C++是最难的语言.这个世界上最难的编程语言可能非C++莫属了.你千万不要以为几天就可以学好C++,C++的学习曲线是相当BT的,你可以看看这篇文章.C++是一门很自由的语 ...
- 荣禄[róng lù]
荣禄[róng lù] 百科名片 荣禄 荣禄(1836年4月6日-1903年4月11日)清末大臣,晚清政治家.字仲华,号略园,瓜尔佳氏,满洲正白旗人,出身于世代军官家庭,以荫生晋工部员外郎,后任内务府 ...
- There was a problem confirming the ssl certificate: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:661) - skipping
Could not fetch URL https://pypi.python.org/simple/xlrd/: There was a problem confirming the ssl cer ...
- 关于Class类的getResource().getPath()方法
程序中配置文件如果放置在classes文件夹,那么我们就可以使用Class类的getResource().getPath()方法获取文件路径. 例如: String path = DBUtil.cla ...