从网页上传图片

时间:2011-04-09 18:54:00

标签: python django curl urllib

我想实现与此http://www.tineye.com/parse?url=yahoo.com类似的功能 - 允许用户从任何网页上传图片。

对我来说,主要的问题是对于拥有大量图片的网页来说需要花费太多时间。

根据下一个方案,我在Django(使用curl或urllib)中这样做:

  1. 抓取页面的html(大页面大约需要1秒):

    file = urllib.urlopen(requested_url)
    html_string = file.read()
    
  2. 使用HTML-parser(BeautifulSoup)解析它,寻找img标签,并将所有src图像写入列表。 (大页面也需要大约1秒)

  3. 检查列表中所有图像的大小,如果它们足够大,则在json响应中返回它们(当网页上有大约80个图像时,需要很长时间约15秒)。这是函数的代码:

  4. 
     def get_image_size(uri):
        file = urllib.urlopen(uri)
        p = ImageFile.Parser()
        data = file.read(1024)
        if not data:
            return None
        p.feed(data)
        if p.image:
            return p.image.size
        file.close()
        #not an image
        return None
    

    正如你所看到的,我没有加载完整的图像来获得它的大小,只有1kb。但是当有很多图像时,它仍然需要花费太多时间(我为每个图像调用此函数一次)。

    那么我怎样才能让它更快地运作?

    可能有没有办法不对每张图片提出要求?

    任何帮助都将受到高度赞赏。

    谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用文件的headers属性,例如urllib2.urlopen返回的对象(我不知道urllib)。

这是我为它写的测试。正如你所看到的,它相当快,但我想有些网站会阻止过多的重复请求。

|milo|laurie|¥ cat test.py
import urllib2
uri = "http://download.thinkbroadband.com/1GB.zip"

def get_file_size(uri):
    file = urllib2.urlopen(uri)
    content_header, = [header for header in file.headers.headers if header.startswith("Content-Length")]
    _, str_length = content_header.split(':')
    length = int(str_length.strip())
    return length

if __name__ == "__main__":
    get_file_size(uri)
|milo|laurie|¥ time python2 test.py
python2 test.py  0.06s user 0.01s system 35% cpu 0.196 total

答案 1 :(得分:1)

我可以想到一些优化:

  1. 在您从流中读取文件时解析
  2. 使用SAX解析器(上面提到的很好)
  3. 使用HEAD获取图像大小
  4. 使用队列来放置您的图像,然后使用几个线程来连接并获取文件大小
  5. HEAD请求示例:

    $ telnet m.onet.pl 80
    Trying 213.180.150.45...
    Connected to m.onet.pl.
    Escape character is '^]'.
    HEAD /_m/33fb7563935e11c0cba62f504d91675f,59,29,134-68-525-303-0.jpg HTTP/1.1
    host: m.onet.pl
    
    HTTP/1.0 200 OK
    Server: nginx/0.8.53
    Date: Sat, 09 Apr 2011 18:32:44 GMT
    Content-Type: image/jpeg
    Content-Length: 37545
    Last-Modified: Sat, 09 Apr 2011 18:29:22 GMT
    Expires: Sat, 16 Apr 2011 18:32:44 GMT
    Cache-Control: max-age=604800
    Accept-Ranges: bytes
    Age: 6575
    X-Cache: HIT from emka1.m10r2.onet
    Via: 1.1 emka1.m10r2.onet:80 (squid)
    Connection: close
    
    Connection closed by foreign host.