Python 下载网页源至关键字

Python 下载网页源至关键字,python,Python,我正在寻找从一个网站下载源代码到一个特定的关键字(这些网站都来自一个论坛,所以我只对第一次发布的用户详细信息的源代码感兴趣),所以我只需要下载源代码,直到我第一次在源代码中找到“” 这个问题虽然用不同的语言表达,但与我想做的非常相似,尽管我对python没有太多经验,所以我不知道如何将答案重新编码到python中。首先,请注意,在取消之前,您可能已经将每个页面的全部或大部分都放入了操作系统缓冲区、NIC、路由器或ISP中,因此,这样做可能毫无益处。如果你提前关闭连接,那么你就不能重复使用连接,

我正在寻找从一个网站下载源代码到一个特定的关键字(这些网站都来自一个论坛,所以我只对第一次发布的用户详细信息的源代码感兴趣),所以我只需要下载源代码,直到我第一次在源代码中找到“”


这个问题虽然用不同的语言表达,但与我想做的非常相似,尽管我对python没有太多经验,所以我不知道如何将答案重新编码到python中。

首先,请注意,在取消之前,您可能已经将每个页面的全部或大部分都放入了操作系统缓冲区、NIC、路由器或ISP中,因此,这样做可能毫无益处。如果你提前关闭连接,那么你就不能重复使用连接,这将带来成本;如果你想提前取消,你必须一次
recv
;等等

如果您大致知道可能需要读取多少字节(最好经常读一点,而不是有时读一点),并且服务器处理HTTP范围请求,那么您可能希望尝试这样做,而不是请求整个文件,然后提前关闭套接字

但是,如果您想知道如何尽早关闭套接字:

urllib2.urlopen
请求
,以及大多数其他高级库都是围绕着您希望读取整个文件的想法设计的。它们在数据进入时缓冲数据,为您提供一个类似于文件的高级接口。最重要的是,他们的API是阻塞的。这两个都不是你想要的。您希望在字节进入时尽可能快地获取字节,并且在关闭套接字时,希望字节尽可能快地位于
recv
之后

这样,您可能想考虑使用Python包装器中的一个围绕代码> LBCURL,这在电源/灵活性和易用性之间提供了很好的平衡。例如,使用

pycurl

import pycurl

buf = ''

def callback(newbuf):
    global buf
    buf += newbuf
    if '<div style="float: right; margin-left: 8px;">' in buf:
        return 0
    return len(newbuf)

c = pycurl.Curl()
c.setopt(c.URL, 'http://curl.haxx.se/dev/')
c.setopt(c.WRITEFUNCTION, callback)
try:
    c.perform()
except Exception as e:
    print(e)
c.close()

print len(buf)
导入pycurl
buf=“”
def回调(newbuf):
全球buf
buf+=newbuf
如果buf中有“”:
返回0
回程透镜(纽伯夫)
c=pycurl.Curl()
c、 setopt(c.URL,'http://curl.haxx.se/dev/')
c、 setopt(c.WRITEFUNCTION,回调)
尝试:
c、 执行
例外情况除外,如e:
打印(e)
c、 关闭()
打印透镜(buf)
事实证明,这最终会在该测试中读取12259/12259字节。但如果我将其更改为前2650字节中的字符串,则只读取2650/12259字节。如果我启动Wireshark和instrument
recv
,我可以看到,尽管下一个数据包确实到达了我的NIC,但我从未真正读过它;我在收到2650字节后立即关闭了套接字。所以,这可能会节省一些时间…虽然可能不会太多。更重要的是,如果我把它扔向一个13MB的图像文件,并试图在1MB后停止,我只收到几KB的额外图像,而且大部分图像甚至还没有到达我的路由器(尽管它可能已经全部离开服务器,如果你关心如何善待服务器的话),这样肯定会节省一些时间

当然,一个典型的论坛页面比13MB更接近12KB。(例如,即使在我漫无目的地说了这么多之后,这个页面仍然不足48KB。)但也许你正在处理非典型论坛

如果页面非常大,您可能希望每次只检查
buf[-len(针):]+newbuf
,而不是整个缓冲区。即使有一个13MB的映像,一遍又一遍地搜索整个过程也不会给总运行时间增加太多,但它确实将我的CPU使用率从1%提高到了9%


最后一件事:如果你正在阅读,比如说,500页,同时阅读,比如说,一次8页,可能会比提前取消每一页节省更多的时间。两者结合在一起可能比单独使用要好,所以这并不是反对这样做的理由,只是一个建议。(如果您想让
curl
为您处理并发性…或者只使用
multiprocessing
concurrent.futures
来使用子进程池,请参见示例。)

直到您在源代码中找到了什么?不知道发生了什么,编辑器解析了html注释,我的问题就解决了,我现在已经修复了它无论你做什么,你都会在一次响应中收到整个网页。将它加载到xml.dom.minidom(或类似的东西)中,以提取所需的部分。为什么要这样做?如果您试图下载巨大的页面,并通过在看到神奇字符串后立即关闭套接字来节省网络带宽或服务器负载……那么,这将需要比简单的Python URL打开函数更低的级别,并且可能不会节省任何带宽或服务器负载。如果这不是你的目标,请解释一下你的目标是什么。我不担心带宽,目标是减少下载每个页面的时间