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解决鸡兔同笼问题的方法
Dec 20 Python
Python MySQLdb Linux下安装笔记
May 09 Python
python实现字符串和日期相互转换的方法
May 13 Python
python中的格式化输出用法总结
Jul 28 Python
python实现求特征选择的信息增益
Dec 18 Python
python实践项目之监控当前联网状态详情
May 23 Python
python打开使用的方法
Sep 30 Python
Python字典中的值为列表或字典的构造实例
Dec 16 Python
使用Keras加载含有自定义层或函数的模型操作
Jun 10 Python
Django Session和Cookie分别实现记住用户登录状态操作
Jul 02 Python
Python类绑定方法及非绑定方法实例解析
Oct 09 Python
Python离线安装openpyxl模块的步骤
Mar 30 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作的文本留言本的例子(四)
2006/10/09 PHP
PHP正则获取页面所有图片地址
2016/03/23 PHP
PHP基于DOM创建xml文档的方法示例
2017/02/08 PHP
PHP实现APP微信支付的实例讲解
2018/02/10 PHP
JavaScript浏览器选项卡效果
2010/08/25 Javascript
JS 实现获取打开一个界面中输入的值
2013/03/19 Javascript
JQuery球队选择实例
2015/05/18 Javascript
jQuery实现tab选项卡效果的方法
2015/07/08 Javascript
location.hash保存页面状态的技巧
2016/04/28 Javascript
AngularJS $injector 依赖注入详解
2016/09/14 Javascript
jquery对table做排序操作的实例演示
2017/08/10 jQuery
js数组方法reduce经典用法代码分享
2018/01/07 Javascript
node内置调试方法总结
2018/02/22 Javascript
vue实现条件判断动态绑定样式的方法
2018/09/29 Javascript
微信小程序 Storage更新详解
2019/07/16 Javascript
JavaScript常用8种数组去重代码实例
2020/09/09 Javascript
ant design pro中可控的筛选和排序实例
2020/11/17 Javascript
Python实现爬取知乎神回复简单爬虫代码分享
2015/01/04 Python
python根据日期返回星期几的方法
2015/07/06 Python
python决策树之C4.5算法详解
2017/12/20 Python
pandas 将list切分后存入DataFrame中的实例
2018/07/03 Python
判断python字典中key是否存在的两种方法
2018/08/10 Python
python判断单向链表是否包括环,若包含则计算环入口的节点实例分析
2019/10/23 Python
使用tensorflow显示pb模型的所有网络结点方式
2020/01/23 Python
使用Python和百度语音识别生成视频字幕的实现
2020/04/09 Python
vscode写python时的代码错误提醒和自动格式化的方法
2020/05/07 Python
CSS3 linear-gradient线性渐变生成加号和减号的方法
2017/11/21 HTML / CSS
商务英语毕业生自荐信范文
2013/11/08 职场文书
党的群众路线教育实践活动批评与自我批评
2014/02/16 职场文书
乔迁之喜主持词
2014/03/27 职场文书
社区巾帼文明岗事迹材料
2014/06/03 职场文书
研究生就业推荐表导师评语
2014/12/31 职场文书
聘用合同范本
2015/09/21 职场文书
教师听课学习心得体会
2016/01/15 职场文书
Windows Server 2012 R2服务器安装与配置的完整步骤
2022/07/15 Servers
win10音频服务未响应怎么解决?win10音频服务未响应未修复的解决方法
2022/08/14 数码科技