繁体   English   中英

我该如何修补lxml?

[英]How do I monkey patch lxml?

我正在使用gevent处理一些网址; 其中一些我使用lxml的etree来检索和解析响应。 当我使用etree.parse(url)检索这些url时,即使我用猴子修补了所有东西,它似乎也被阻止了。 如果我通过请求检索,则不会发生阻塞。

import time
import gevent
from lxml import etree
from gevent import monkey
monkey.patch_all()
import requests

def first():
    url = 'http://www.google.com'
    r = requests.get(url)
    return r

def second():
    url = 'http://url_to_large_xml_that_requires_api_key'
    r = etree.parse(url)  # this blocks "first()"
    #r = requests.get(url)
    return r

def get_external(i):
    if i == 'first':
        return first()
    elif i == 'second':
        return second()

threads = [gevent.spawn(get_external, i) for i in ['first', 'second']]
gevent.joinall(threads)

如果我取消注释r = requests.get(url)并注释掉r = etree.parse(url)那么整个脚本将运行得更快,并且不会first阻塞。 我知道一个解决方案可能是先获取请求,然后再通过etree处理该问题,但我想了解为什么etree首先会阻塞。

如所记载, gevent.monkey使Python标准库与gevent的模型协作。

lxml不属于标准库; 因此, gevent.monkey不支持它gevent.monkey

确实,如果您查看模块文档 ,就会发现它知道如何打补丁的目标模块的列表。 socket是集合的成员; lxml当然不是。


因此,对于更大的问题-“如何为gevent支持猴子lxml补丁”的答案? 从“首先,编写支持gevent模型的基础调用的实现”开始。

但是,由于lxml根植于C而不是驻留在Python中,因此除非接口以一种可访问的方式清楚地抽象化,而且lxml的open()调用不受猴子对套接字模块的影响是,一个明确的指示(例如,与请求模块不同),它使用的是libxml2的本机功能,而不是Python套接字模块。 最好的选择是按计划进行,从解析操作中进行带外检索。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM