python使用tornado实现简单爬虫


Posted in Python onJuly 28, 2018

本文实例为大家分享了python使用tornado实现简单爬虫的具体代码,供大家参考,具体内容如下

代码在官方文档的示例代码中有,但是作为一个tornado新手来说阅读起来还是有点困难的,于是我在代码中添加了注释,方便理解,代码如下:

# coding=utf-8
 #!/usr/bin/env python

import time
from datetime import timedelta

try:
  from HTMLParser import HTMLParser
  from urlparse import urljoin, urldefrag
except ImportError:
  from html.parser import HTMLParser
  from urllib.parse import urljoin, urldefrag

from tornado import httpclient, gen, ioloop, queues

 # 设置要爬取的网址
base_url = 'http://www.baidu.com'
 # 设置worker数量
concurrency = 10
 # 此代码会获取base_url下的所有其他url
@gen.coroutine
def get_links_from_url(url):

  try:
    # 通过异步向url发起请求
    response = yield httpclient.AsyncHTTPClient().fetch(url)
    print('fetched %s' % url)
    # 响应如果是字节类型 进行解码
    html = response.body if isinstance(response.body, str) \
      else response.body.decode(errors='ignore')
    # 构建url列表
    urls = [urljoin(url, remove_fragment(new_url))
        for new_url in get_links(html)]
  except Exception as e:
    print('Exception: %s %s' % (e, url))
    # 报错返回空列表
    raise gen.Return([])
  # 返回url列表
  raise gen.Return(urls)


def remove_fragment(url):
  #去除锚点
  pure_url, frag = urldefrag(url)

  return pure_url


def get_links(html):
  #从html页面里提取url
  class URLSeeker(HTMLParser):
    def __init__(self):
      HTMLParser.__init__(self)
      self.urls = []

    def handle_starttag(self, tag, attrs):
      href = dict(attrs).get('href')
      if href and tag == 'a':
        self.urls.append(href)

  url_seeker = URLSeeker()
  url_seeker.feed(html)
  return url_seeker.urls


@gen.coroutine
def main():
  # 创建队列
  q = queues.Queue()
  # 记录开始时间戳
  start = time.time()
  # 构建两个集合
  fetching, fetched = set(), set()

  @gen.coroutine
  def fetch_url():
    # 从队列中取出数据
    current_url = yield q.get()
    try:
      # 如果取出的数据在队列中已经存在 返回
      if current_url in fetching:
        return

      print('fetching %s' % current_url)
      # 如果不存在添加到集合当中
      fetching.add(current_url)
      # 从新放入的链接中继续获取链接
      urls = yield get_links_from_url(current_url)
      # 将已经请求玩的url放入第二个集合
      fetched.add(current_url)

      for new_url in urls:
        # Only follow links beneath the base URL
        # 如果链接是以传入的url开始则放入队列
        if new_url.startswith(base_url):
          yield q.put(new_url)

    finally:
      # 队列内数据减一
      q.task_done()

  @gen.coroutine
  def worker():
    while True:
      # 保证程序持续运行
      yield fetch_url()
  # 将第一个url放入队列
  q.put(base_url)

  # Start workers, then wait for the work queue to be empty.
  for _ in range(concurrency):
    # 启动对应数量的worker
    worker()
  # 等待队列数据处理完成
  yield q.join(timeout=timedelta(seconds=300))
  # 如果两个集合不相等抛出异常
  assert fetching == fetched
  # 打印执行时间
  print('Done in %d seconds, fetched %s URLs.' % (
    time.time() - start, len(fetched)))


if __name__ == '__main__':
  io_loop = ioloop.IOLoop.current()
  io_loop.run_sync(main)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
为Python的web框架编写MVC配置来使其运行的教程
Apr 30 Python
python实现unicode转中文及转换默认编码的方法
Apr 29 Python
tensorflow获取变量维度信息
Mar 10 Python
python如何统计序列中元素
Jul 31 Python
pandas string转dataframe的方法
Apr 11 Python
pycharm 取消默认的右击运行unittest的方法
Nov 29 Python
pytorch对可变长度序列的处理方法详解
Dec 08 Python
利用python实现简易版的贪吃蛇游戏(面向python小白)
Dec 30 Python
Python3.5 Pandas模块之Series用法实例分析
Apr 23 Python
基于python解线性矩阵方程(numpy中的matrix类)
Oct 21 Python
python绘制彩虹图
Dec 16 Python
使用python实现学生信息管理系统
Feb 25 Python
python编写简易聊天室实现局域网内聊天功能
Jul 28 #Python
对tensorflow 的模型保存和调用实例讲解
Jul 28 #Python
Python Socket编程之多线程聊天室
Jul 28 #Python
python实现点对点聊天程序
Jul 28 #Python
基于python实现聊天室程序
Jul 27 #Python
Python中return self的用法详解
Jul 27 #Python
TensorFlow打印tensor值的实现方法
Jul 27 #Python
You might like
php生成固定长度纯数字编码的方法
2015/07/09 PHP
Yii框架实现多数据库配置和操作的方法
2017/05/25 PHP
创建无限极分类树型结构的简单方法
2017/06/20 PHP
<script defer> defer 是什么意思
2009/05/10 Javascript
javascript Demo模态窗口
2009/12/06 Javascript
JavaScript开发规范要求(规范化代码)
2010/08/16 Javascript
Dom与浏览器兼容性说明
2010/10/25 Javascript
Jquery下:nth-child(an+b)的使用注意
2011/05/28 Javascript
浅析document.createDocumentFragment()与js效率
2013/07/08 Javascript
实现js保留小数点后N位的代码
2014/11/13 Javascript
JavaScript对象数组的排序处理方法
2015/10/21 Javascript
快速解决js中window.location.href不工作的问题
2016/11/02 Javascript
javascript实现简单的ajax封装示例
2016/12/28 Javascript
tablesorter.js表格排序使用方法(支持中文排序)
2017/02/10 Javascript
BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传、预览、提交的导入Excel数据操作步骤
2017/08/07 Javascript
vue component 中引入less文件报错 Module build failed
2019/04/17 Javascript
解析JS在获取当前月的最后一天遇到的坑
2019/08/30 Javascript
vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件
2021/02/20 Vue.js
Python命名空间详解
2014/08/18 Python
windows下python连接oracle数据库
2017/06/07 Python
利用python实现xml与数据库读取转换的方法
2017/06/17 Python
python3+PyQt5 实现Rich文本的行编辑方法
2019/06/17 Python
树莓派用python中的OpenCV输出USB摄像头画面
2019/06/22 Python
Django 静态文件配置过程详解
2019/07/23 Python
python爬虫模块URL管理器模块用法解析
2020/02/03 Python
Python 实现国产SM3加密算法的示例代码
2020/09/21 Python
解决Pycharm 运行后没有输出的问题
2021/02/05 Python
CSS3制作炫酷带方向感应的鼠标滑过图片3D动画
2016/03/16 HTML / CSS
使用html2canvas.js实现页面截图并显示或上传的示例代码
2018/12/18 HTML / CSS
Clarria化妆品官方网站:购买天然和有机化妆品系列
2018/04/08 全球购物
企业党员公开承诺书
2014/03/26 职场文书
公司请假条格式
2014/04/11 职场文书
青涩记忆观后感
2015/06/18 职场文书
小学课改工作总结
2015/08/13 职场文书
2016年优秀党员教师先进事迹材料
2016/02/29 职场文书
2019年销售部季度工作计划3篇
2019/10/09 职场文书