python使用tornado实现简单爬虫

 更新时间:2018年07月28日 09:08:58   作者:WangF0  
这篇文章主要为大家详细介绍了python使用tornado实现简单爬虫,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了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)

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

相关文章

  • python3爬虫学习之数据存储txt的案例详解

    python3爬虫学习之数据存储txt的案例详解

    这篇文章主要介绍了python3爬虫学习之数据存储txt的案例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Python编程中类与类的关系详解

    Python编程中类与类的关系详解

    在本文里小编给大家整理了关于Python编程中类与类的关系以及相关代码知识点,需要的朋友们可以学习下。
    2019-08-08
  • pycharm终端无法激活conda环境的解决办法

    pycharm终端无法激活conda环境的解决办法

    如果您在PyCharm终端中无法激活conda环境,可能是由于PyCharm没有正确配置conda解释器,这篇文章主要给大家介绍了关于pycharm终端无法激活conda环境的解决办法,需要的朋友可以参考下
    2023-09-09
  • jupyter读取错误格式文件的解决方案

    jupyter读取错误格式文件的解决方案

    这篇文章主要介绍了jupyter读取错误格式文件的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • python基础之错误和异常处理

    python基础之错误和异常处理

    这篇文章主要介绍了python错误和异常处理,实例分析了Python中返回一个返回值与多个返回值的方法,需要的朋友可以参考下
    2021-10-10
  • Python sorted对list和dict排序

    Python sorted对list和dict排序

    这篇文章主要介绍了Python sorted对list和dict排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • 浅谈pandas中对nan空值的判断和陷阱

    浅谈pandas中对nan空值的判断和陷阱

    这篇文章主要介绍了浅谈pandas中对nan空值的判断和陷阱,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • python中用ggplot绘制画图实例讲解

    python中用ggplot绘制画图实例讲解

    在本篇文章里小编给大家整理的是一篇关于python中用ggplot绘制画图实例讲解内容,有兴趣的朋友们可以学习参考下。
    2021-01-01
  • 一些关于python 装饰器的个人理解

    一些关于python 装饰器的个人理解

    这篇文章主要介绍了python 装饰器的一些理解,希望可以帮助大家更好的学习和使用python,感兴趣的朋友可以了解下
    2020-08-08
  • python实现由数组生成对称矩阵

    python实现由数组生成对称矩阵

    本文给大家分享的是由数组生成对称矩阵的思路并附上了使用Python实现的代码,希望大家能够喜欢
    2021-05-05

最新评论