0

我想在 python 中构建一个需要获取 url 的小脚本。虽然服务器有点蹩脚,但它回复纯 ASCII 而没有任何标题。

当我尝试:

import urllib.request
response = urllib.request.urlopen(url)
print(response.read())

我收到一个http.client.BadStatusLine: 100错误,因为这不是格式正确的 HTTP 响应。

是否有另一种方法来获取 url 并获取原始内容,而无需尝试解析响应?

谢谢

4

3 回答 3

1

如果没有更多信息,很难回答您的直接问题;不确切知道有问题的(网络)服务器是如何损坏的。

也就是说,您可以尝试使用一些较低级别的东西socket ,例如。这是一种方式(python2.x 风格,未经测试):

#!/usr/bin/env python
import socket                                                                  
from urlparse import urlparse                                                  

def geturl(url, timeout=10, receive_buffer=4096):                              
    parsed = urlparse(url)                                                     
    try:                                                                       
        host, port = parsed.netloc.split(':')                                  
    except ValueError:                                                         
        host, port = parsed.netloc, 80                                         

    sock = socket.create_connection((host, port), timeout)                     
    sock.sendall('GET %s HTTP/1.0\n\n' % parsed.path)                          

    response = [sock.recv(receive_buffer)]                                     
    while response[-1]:                                                        
        response.append(sock.recv(receive_buffer))                             

    return ''.join(response)  

print geturl('http://www.example.com/') #<- the trailing / is needed if no 
                                            other path element is present

这是一个 python3.2 转换的尝试(例如,如果将响应写入文件,您可能不需要从字节解码):

#!/usr/bin/env python
import socket                                                                  
from urllib.parse import urlparse                                                  

ENCODING = 'ascii'

def geturl(url, timeout=10, receive_buffer=4096):                              
    parsed = urlparse(url)                                                     
    try:                                                                       
        host, port = parsed.netloc.split(':')                                  
    except ValueError:                                                         
        host, port = parsed.netloc, 80                                         

    sock = socket.create_connection((host, port), timeout)                     

    method  = 'GET %s HTTP/1.0\n\n' % parsed.path
    sock.sendall(bytes(method, ENCODING))

    response = [sock.recv(receive_buffer)]                                     
    while response[-1]:                                                        
        response.append(sock.recv(receive_buffer))                             

    return ''.join(r.decode(ENCODING) for r in response)

print(geturl('http://www.example.com/'))

编辑:您可能需要调整您在请求中输入的内容,具体取决于相关的 Web 服务器。Guanidene 的出色答案提供了多种资源来指导您走上这条道路。

于 2012-04-11T15:44:06.290 回答
1

在这种情况下,您需要做的是send a raw HTTP request using sockets.
在这种情况下,您需要使用socketpython 模块进行一些低级网络编程。(网络套接字实际上将服务器发送的所有信息返回给您as it as,因此您可以根据需要相应地解释响应。例如,HTTP 协议根据标准 HTTP 标头 - GET、POST、HEAD 等来解释响应。高级模块urllib对您隐藏此标头信息并仅返回数据。)

您还需要了解一些有关 HTTP 标头的基本信息。对于您的情况,您只需要了解GETHTTP 请求。在此处查看其定义 - http://djce.org.uk/dumprequest,在此处查看它的示例 - http://en.wikipedia.org/wiki/HTTP#Example_session。(如果您希望捕获从浏览器发送的 HTTP 请求的实时跟踪,则需要像wireshark这样的数据包嗅探软件。)

一旦您了解了有关socket模块和的基础知识HTTP headers,您就可以通过这个示例 - http://coding.debuntu.org/python-socket-simple-tcp-client告诉您如何通过套接字将 HTTP 请求发送到服务器和读回它的回复。您也可以在 SO 上参考这个不清楚的问题。

(您可以谷歌python socket http获取更多示例。)

(提示:我不是 Java 爱好者,但是,如果你在 python 下没有找到足够令人信服的例子,请尝试在 Java 下找到它,然后将其相应地翻译成 python。)

于 2012-04-11T15:41:13.357 回答
0
urllib.urlretrieve('http://google.com/abc.jpg', 'abc.jpg')
于 2012-04-11T14:25:05.327 回答