如何在 python 中使用 urllib2 加快获取页面的速度?

2024-05-17

我有一个脚本可以获取多个网页并解析信息。

(一个例子可以在 )

我在上面运行了 cProfile,正如我所假设的,urlopen 占用了很多时间。有没有办法更快地获取页面?或者一次获取多个页面的方法?我会做最简单的事情,因为我是 python 和网络开发的新手。

提前致谢! :)

更新:我有一个名为fetchURLs(),我用它来制作我需要的 URL 数组 所以像urls = fetchURLS().URL 都是来自 Amazon 和 eBay API 的 XML 文件(这让我很困惑为什么加载时间这么长,也许我的虚拟主机很慢?)

我需要做的是加载每个 URL,读取每个页面,并将该数据发送到脚本的另一部分,该部分将解析并显示数据。

请注意,在获取所有页面之前我无法执行后一部分,这就是我的问题所在。

另外,我相信我的主机一次只能处理 25 个进程,所以服务器上最简单的就很好了:)


这是时间:

Sun Aug 15 20:51:22 2010    prof

         211352 function calls (209292 primitive calls) in 22.254 CPU seconds

   Ordered by: internal time
   List reduced from 404 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       10   18.056    1.806   18.056    1.806 {_socket.getaddrinfo}
     4991    2.730    0.001    2.730    0.001 {method 'recv' of '_socket.socket' objects}
       10    0.490    0.049    0.490    0.049 {method 'connect' of '_socket.socket' objects}
     2415    0.079    0.000    0.079    0.000 {method 'translate' of 'unicode' objects}
       12    0.061    0.005    0.745    0.062 /usr/local/lib/python2.6/HTMLParser.py:132(goahead)
     3428    0.060    0.000    0.202    0.000 /usr/local/lib/python2.6/site-packages/BeautifulSoup.py:1306(endData)
     1698    0.055    0.000    0.068    0.000 /usr/local/lib/python2.6/site-packages/BeautifulSoup.py:1351(_smartPop)
     4125    0.053    0.000    0.056    0.000 /usr/local/lib/python2.6/site-packages/BeautifulSoup.py:118(setup)
     1698    0.042    0.000    0.358    0.000 /usr/local/lib/python2.6/HTMLParser.py:224(parse_starttag)
     1698    0.042    0.000    0.275    0.000 /usr/local/lib/python2.6/site-packages/BeautifulSoup.py:1397(unknown_starttag)

EDIT:我正在扩展答案以包含一个更精美的示例。我在这篇文章中发现了很多关于线程与线程的敌意和错误信息。异步 I/O。因此我还添加了更多的论据来反驳某些无效的主张。我希望这将帮助人们为正确的工作选择正确的工具。

这是三天前的一个问题的重复。

Python urllib2.open 很慢,需要更好的方法来读取多个网址 - 代码日志Python urllib2.urlopen() 很慢,需要更好的方法来读取多个 url https://stackoverflow.com/questions/3472515/python-urllib2-open-is-slow-need-a-better-way-to-read-several-urls/3472905#3472905

我正在完善代码以展示如何使用线程并行获取多个网页。

import time
import threading
import Queue

# utility - spawn a thread to execute target for each args
def run_parallel_in_threads(target, args_list):
    result = Queue.Queue()
    # wrapper to collect return value in a Queue
    def task_wrapper(*args):
        result.put(target(*args))
    threads = [threading.Thread(target=task_wrapper, args=args) for args in args_list]
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    return result

def dummy_task(n):
    for i in xrange(n):
        time.sleep(0.1)
    return n

# below is the application code
urls = [
    ('http://www.google.com/',),
    ('http://www.lycos.com/',),
    ('http://www.bing.com/',),
    ('http://www.altavista.com/',),
    ('http://achewood.com/',),
]

def fetch(url):
    return urllib2.urlopen(url).read()

run_parallel_in_threads(fetch, urls)

正如您所看到的,应用程序特定的代码只有 3 行,如果您积极的话,可以将其折叠为 1 行。我认为没有人可以证明他们的说法是合理的,即这是复杂且无法维护的。

不幸的是,这里发布的大多数其他线程代码都有一些缺陷。他们中的许多人都会主动轮询以等待代码完成。join()是同步代码的更好方法。我认为这段代码已经改进了迄今为止的所有线程示例。

保持连接

如果所有 URL 都指向同一服务器,WoLpH 关于使用保持活动连接的建议可能非常有用。

twisted

亚伦·加拉格尔是以下人士的粉丝twisted框架,他敌视任何建议线程的人。不幸的是,他的许多说法都是错误信息。例如,他说“-1 表示建议线程。这是 IO 绑定的;线程在这里毫无用处。”这与证据相反,因为 Nick T 和我都证明了使用线程的速度增益。事实上,I/O 密集型应用程序可以从使用 Python 线程中获得最大收益(而 CPU 密集型应用程序则没有任何收益)。 Aaron 对线程的误导性批评表明他对一般的并行编程相当困惑。

正确的工具适合正确的工作

我很清楚与使用线程、Python、异步 I/O 等进行并行编程有关的问题。每个工具都有其优点和缺点。对于每种情况都有合适的工具。我并不反对扭曲(尽管我自己还没有部署过)。但我不相信我们可以断然地说在所有情况下线都是坏的,而扭曲的都是好的。

例如,如果OP的要求是并行获取10,000个网站,则异步I/O将是首选。线程是不合适的(除非使用无堆栈Python)。

Aaron 对线程的反对大多是概括性的。他没有意识到这是一个微不足道的并行化任务。每个任务都是独立的,不共享资源。所以他的大部分攻击都不适用。

鉴于我的代码没有外部依赖性,我将其称为适合正确工作的正确工具。

表现

我想大多数人都会同意这个任务的性能在很大程度上取决于网络代码和外部服务器,其中平台代码的性能影响可以忽略不计。然而,Aaron 的基准测试显示,线程代码的速度提高了 50%。我认为有必要对这种明显的速度增益做出反应。

在尼克的代码中,有一个明显的缺陷导致效率低下。但是你如何解释我的代码获得的 233 毫秒的速度增益?我想即使是扭曲的粉丝也不会轻易下结论,将这归因于扭曲的效率。毕竟,系统代码之外还有大量的变量,例如远程服务器的性能、网络、缓存以及 urllib2 和twisted web 客户端之间的差异实现等。

为了确保 Python 的线程不会导致大量低效率,我做了一个快速基准测试来生成 5 个线程,然后生成 500 个线程。我可以很轻松地说,生成 5 个线程的开销可以忽略不计,并且无法解释 233 毫秒的速度差异。

In [274]: %time run_parallel_in_threads(dummy_task, [(0,)]*5)
CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 0.00 s
Out[275]: <Queue.Queue instance at 0x038B2878>

In [276]: %time run_parallel_in_threads(dummy_task, [(0,)]*500)
CPU times: user 0.16 s, sys: 0.00 s, total: 0.16 s
Wall time: 0.16 s

In [278]: %time run_parallel_in_threads(dummy_task, [(10,)]*500)
CPU times: user 1.13 s, sys: 0.00 s, total: 1.13 s
Wall time: 1.13 s       <<<<<<<< This means 0.13s of overhead

对我的并行获取的进一步测试显示,17 次运行中响应时间存在巨大差异。 (不幸的是,我没有扭曲验证亚伦的代码)。

0.75 s
0.38 s
0.59 s
0.38 s
0.62 s
1.50 s
0.49 s
0.36 s
0.95 s
0.43 s
0.61 s
0.81 s
0.46 s
1.21 s
2.87 s
1.04 s
1.72 s

我的测试并不支持 Aaron 的结论,即线程始终比异步 I/O 慢很多。考虑到涉及的变量数量,我不得不说这不是衡量异步 I/O 和线程之间系统性能差异的有效测试。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 python 中使用 urllib2 加快获取页面的速度? 的相关文章

  • 在 Pandas 中按日期获取有效合约

    我在检测 pandas DataFrame 中的活动合约方面遇到了一些困难 假设每一行都是一个协商 对于每一行 我有两列 initial date 和 end date 我想知道的是按日期划分的活跃合约数量 到目前为止我做了一个非常低效的方
  • 在 Python 中使用 Selenium 处理“接受 Cookie”弹出窗口

    我一直在尝试用硒抓取这个房地产网站的一些信息 但是 当我访问该网站时 我需要接受 cookie 才能继续 这仅在机器人访问网站时发生 而不是在我手动执行时发生 当我尝试通过 xpath 或 id 查找相应的元素时 正如我在手动检查页面时找到
  • 行未从树视图复制

    该行未在树视图中复制 我在按行并复制并粘贴到未粘贴的任何地方后制作了弹出复制 The code popup tk Menu tree opportunity tearoff 0 def row copy item tree opportun
  • 在 Numpy 中切片后确定结果数组的形状

    我很难理解在 numpy 中切片后如何确定结果数组的形状 例如 我使用以下简单代码 import numpy as np array np arange 27 reshape 3 3 3 slice1 array 1 2 1 slice2
  • 一次将Python dict的内容分配给多个变量?

    我想做这样的事情 def f return a 1 b 2 c 3 a b f or a b f IE 这样 a 被分配为 1 b 被分配为 2 并且 c 是未定义的 这与此类似 def f return 1 2 a b f 依赖于变量名称
  • Tensorflow 可变图像输入大小(自动编码器、放大......)

    Edit WARNING不建议使用不同图像大小的图像 因为张量需要具有相同的大小才能实现并行化 我一直在寻找解决方案 了解如何使用不同大小的图像作为神经网络的输入 Numpy 第一个想法是使用numpy 然而 由于每个图像的大小不同 我无法
  • python - 是否可以扩展 xml-rpc 可以序列化的事物集?

    我看到几个问题询问如何发送numpy ndarray通过 xml rpc 调用 这不能开箱即用 因为正如 xml rpc 中所述docs https docs python org 2 library xmlrpclib html 有一组固
  • python 中分割字符串以获得一个值?

    需要帮助 假设我在名为 input 的变量中有一个字符串 Sam Person name kind input split 通过执行上述操作 我得到两个具有不同字符串 Sam 和 Person 的变量 有没有办法只获取第一个值 name S
  • Pandas重置索引未生效[重复]

    这个问题在这里已经有答案了 我不确定我在哪里误入歧途 但我似乎无法重置数据帧上的索引 当我跑步时test head 我得到以下输出 正如您所看到的 数据帧是一个切片 因此索引超出范围 我想做的是重置该数据帧的索引 所以我跑test rese
  • 带图像的简单 GUI [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我试图在简单的 GUI 上显示一些卡
  • 错误:permission_manager_qt.cpp(82) 不支持的权限类型:13

    我正在开发具有内置浏览器功能的 python 代码 PyQt 5 13 import sys from PyQt5 QtCore import from PyQt5 QtGui import from PyQt5 QtWidgets imp
  • 如果字段值在外部列表中,Django 会注释布尔值

    想象一下我有这个 Django 模型 class Letter models Model name models CharField max length 1 unique True 还有这个列表 vowels a e i o u 我想查询
  • Python Kivy - 在本机网络浏览器中打开 url 的应用程序

    我尝试制作一个简单的应用程序 在单击 Screen One 上的按钮后 在 Kivy 中打开一个网页 我使用了这个主题 Python 在应用程序中直接显示网络浏览器 iframe https stackoverflow com questi
  • 在径向(树)网络x图中查找末端节点(叶节点)

    给定下图 是否有一种方便的方法来仅获取末端节点 我所说的端节点是指那些具有一个连接边的到节点 我认为这些有时被称为叶节点 G nx DiGraph fromnodes 0 1 1 1 1 1 2 3 4 5 5 5 7 8 9 10 ton
  • 如何列出 python PDB 中的当前行?

    在 perl 调试器中 如果重复列出离开当前行的代码段 可以通过输入命令返回到当前行 点 我无法使用 python PDB 模块找到任何类似的东西 如果我list如果我自己离开当前行并想再次查看它 似乎我必须记住当前正在执行的行号 对我来说
  • Django 在选择列表更改时创建毫无意义的迁移

    我正在尝试使用可调用创建一个带有选择字段的模型 以便 Django 在选择列表更改时不会创建迁移 如中所述this https stackoverflow com questions 31788450 stop django from cr
  • select() 可以在 Windows 下使用 Python 中的文件吗?

    我正在尝试在 Windows 下运行以下 python 服务器 An echo server that uses select to handle multiple clients at a time Entering any line o
  • 查找给定节点的最高权重边

    我在 NetworkX 中有一个有向图 边缘的权重从 0 到 1 表示它们发生的概率 网络连通性非常高 所以我想修剪每个节点的边缘 只保留最高概率的节点 我不确定如何迭代每个节点并仅保留最高权重in edges在图中 有没有一个networ
  • TypeError:无法使用抽象方法实例化抽象类 <...>

    这是我的代码 from abc import ABC from abc import abstractmethod class Mamifiero ABC docstring for Mamifiero def init self self
  • 使用 Python 生成类似于 Messenger 或 kik 代码的圆形二维码

    我可以使用 Python 生成圆形 QR 码 就像 Facebook Messenger 或 kik 使用的那样吗 我访问了很多网站 但找不到这种类型的二维码 默认情况下 Python 生成方形 QR 码 但在我的项目中我想要圆形 QR 码

随机推荐

  • Rails - 渲染:目标锚标记的操作?

    我希望像这样使用渲染 render action gt page form 我也尝试过这个 render template gt site page form 那也没用 这个特定页面上的表单位于最底部 如果提交时发生任何错误 我不希望用户被
  • java中void的作用是什么?

    返回类型 方法返回值的数据类型 如果方法不返回值 则返回 void http download oracle com javase tutorial java javaOO methods html http download oracle
  • 是否可以使用 Dapper 流式传输大型 SQL Server 数据库结果集?

    我需要从数据库返回大约 500K 行 请不要问为什么 然后 我需要将这些结果保存为 XML 更紧急 并将该文件通过 ftp 传输到某个神奇的地方 我还需要转换结果集中的每一行 现在 这就是我正在做的事情 TOP 100结果 使用 Dappe
  • 描述符“join”需要“unicode”对象,但收到“str”

    代码改编自here http wiki geany org howtos convert camelcase from foo bar to Foo Bar def lower case underscore to camel case s
  • 使用 paramiko 运行 Sudo 命令

    我正在尝试执行sudo使用 python paramiko 在远程计算机上运行命令 我尝试了这段代码 import paramiko ssh paramiko SSHClient ssh set missing host key polic
  • 对象指针值作为字典的键

    我想使用对象的引用值作为字典的键 而不是对象值的副本 因此 我本质上想在字典中存储与另一个对象的特定实例关联的对象 并稍后检索该值 这可能吗 是不是完全违背了NSDictionary的理念 我可以看出我可能以错误的方式处理这个问题 因为字典
  • 为什么 try catch 块没有捕获 Promise 异常?

    我对承诺的错误处理感到困惑 答案可能很明显 但我不明白 我有以下示例代码 var test async function throw new Error Just another error try test then catch err
  • HTML 表格 - 固定列宽和多个可变列宽

    我必须建立一个有 5 列的表 表格宽度是可变的 内容宽度的 50 有些列包含固定大小的按钮 因此这些列应该有一个固定大小 例如 100px 有些列中有文本 所以我希望这些列具有可变的列宽 例如 Column1 tablewidth sum
  • 通过 Telnet 运行应用程序

    我需要创建一个 BAT 文件来通过 telnet 运行应用程序 但据我所知 在 DOS 上无法执行此操作 Telnet 不允许在连接的瞬间向远程计算机发送任何命令 并且 BAT 文件中的每个后续命令只有在 telnet 停止后才会执行 这段
  • R data.table 1.9.2 关于 setkey 的问题

    这似乎是 1 8 10 后引入的一个错误 与包含列表的 DT 的 setkey 相关 运行下面两个代码来查看问题 library data table dtl lt list dtl 1 lt data table scenario 1 p
  • 更改屏幕方向时,创建了新活动

    我对 Android 还比较陌生 但在过去的一年里制作了很多应用程序 所以请原谅我 我知道 当您在设备上运行应用程序并通过旋转设备来更改屏幕方向时 所显示的活动将完全重新创建 我转到 YouTube 应用程序 我使用的是 Nexus 7 w
  • 在 android 中从 XML 文件创建视图对象

    我只想从 xml 布局文件中获取一个对象 而不必将其实现到当前布局中 我知道方法 LayoutInflater from context inflate R layout myfile myparent true 但执行上述操作后 布局将被
  • 为什么Java不提供运算符重载?

    从 C 到 Java 明显的未解决问题是为什么 Java 不包含运算符重载 Isn t Complex a b c a b c 比简单得多Complex a b c a b add c 是否有已知的原因 有效的论据not允许运算符重载 原因
  • 是否可以在 OpenCL 中并行运行求和计算?

    我是 OpenCL 的新手 不过 我了解 C C 基础知识和 OOP 我的问题如下 是否可以以某种方式并行运行求和计算任务 理论上可能吗 下面我将描述我尝试做的事情 任务例如是 double values new double 1000 l
  • 以编程方式更改任务栏图标(Win32,C++)[重复]

    这个问题在这里已经有答案了 我有一个 C win32 程序 我想在运行时编辑任务栏图标以显示有关该程序的警报等 但是我对 win32 api 不太有经验 而且我找不到任何东西在线的 我发现的最接近的是http www windows tec
  • Django:分解视图

    这实际上只是一个 最佳实践 问题 我发现在开发应用程序时 我经常会遇到a lot的意见 将这些视图分成几个视图文件是常见的做法吗 换句话说 不仅仅是views py 通常还有views 1 py views 2 py views 3 py
  • 将 MahApps 图标与 ContextMenu 结合使用

    我正在使用 MahApps Metro UI 工具包编写 WPF 应用程序 http mahapps com guides quick start html http mahapps com guides quick start html
  • 两个 pandas 列的字符串连接

    我有一个关注者DataFrame from pandas import df DataFrame foo a b c bar 1 2 3 它看起来像这样 bar foo 0 1 a 1 2 b 2 3 c 现在我想要这样的东西 bar 0
  • vb.net HtmlAgilityPack 在 div 之后插入字符串

    我试图在 div 末尾直接插入一些我自己的 html 这个 div 里面有其他 div Dim HtmlNode As HtmlNode HtmlNode CreateNode span class Those were the frien
  • 如何在 python 中使用 urllib2 加快获取页面的速度?

    我有一个脚本可以获取多个网页并解析信息 一个例子可以在 我在上面运行了 cProfile 正如我所假设的 urlopen 占用了很多时间 有没有办法更快地获取页面 或者一次获取多个页面的方法 我会做最简单的事情 因为我是 python 和网