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 相关文章推荐
json跨域调用python的方法详解
Jan 11 Python
python使用mysql数据库示例代码
May 21 Python
使用DataFrame删除行和列的实例讲解
Apr 08 Python
selenium+python 对输入框的输入处理方法
Oct 11 Python
使用Python实现从各个子文件夹中复制指定文件的方法
Oct 25 Python
python原类、类的创建过程与方法详解
Jul 19 Python
python实现高斯判别分析算法的例子
Dec 09 Python
Python双链表原理与实现方法详解
Feb 22 Python
Python利用matplotlib绘制折线图的新手教程
Nov 05 Python
python中str内置函数用法总结
Dec 27 Python
解决pytorch 保存模型遇到的问题
Mar 03 Python
还在手动盖楼抽奖?教你用Python实现自动评论盖楼抽奖(一)
Jun 07 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登录(ajax提交数据和后台校验)实例分享
2016/12/29 PHP
PHP实现限制IP访问的方法
2017/04/20 PHP
javascript setAttribute, getAttribute 在不同浏览器上的不同表现
2010/08/05 Javascript
js实现倒计时时钟的示例代码
2013/12/17 Javascript
Node.js与PHP、Python的字符处理性能对比
2014/07/06 Javascript
javascript实现的一个随机点名功能
2014/08/26 Javascript
使用js实现数据格式化
2014/12/03 Javascript
jquery加载图片时以淡入方式显示的方法
2015/01/14 Javascript
javascript中scrollTop详解
2015/04/13 Javascript
基于jQuery实现表格内容的筛选功能
2016/08/21 Javascript
探索Javascript中this的奥秘
2016/12/11 Javascript
Bootstrap缩略图与警告框学习使用
2017/02/08 Javascript
详解vue-cli之webpack3构建全面提速优化
2017/12/25 Javascript
使用Vue.js开发微信小程序开源框架mpvue解析
2018/03/20 Javascript
详解Vue基于 Nuxt.js 实现服务端渲染(SSR)
2018/04/05 Javascript
vue实现歌手列表字母排序下拉滚动条侧栏排序实时更新
2019/05/14 Javascript
详解Vue中组件传值的多重实现方式
2019/08/16 Javascript
layui table 表格上添加日期控件的两种方法
2019/09/28 Javascript
js实现开关灯效果
2020/03/30 Javascript
使用python绘制人人网好友关系图示例
2014/04/01 Python
Python遍历文件夹和读写文件的实现方法
2017/05/10 Python
python+requests+unittest API接口测试实例(详解)
2017/06/10 Python
对python3中pathlib库的Path类的使用详解
2018/10/14 Python
使用Python快乐学数学Github万星神器Manim简介
2019/08/07 Python
基于PyInstaller各参数的含义说明
2021/03/04 Python
css sprite简单实例
2016/05/23 HTML / CSS
html5自动播放mov格式视频的实例代码
2020/01/14 HTML / CSS
波兰数码相机及配件网上商店: Cyfrowe.pl
2017/06/19 全球购物
MAC彩妆英国官网:M·A·C UK
2018/05/30 全球购物
二年级体育教学反思
2014/01/15 职场文书
幼儿园中班评语大全
2014/04/17 职场文书
投资意向书
2014/07/30 职场文书
会议欢迎词范文
2015/01/27 职场文书
公司出纳岗位职责
2015/03/31 职场文书
详解Python为什么不用设计模式
2021/06/24 Python
鲲鹏 CentOS 7 安装Python3.7
2022/05/11 Servers