我想在python中构建一个需要获取url的小脚本。虽然服务器是一种蹩脚的回复纯粹的ASCII,没有任何标题。
当我尝试:
import urllib.request
response = urllib.request.urlopen(url)
print(response.read())
我收到http.client.BadStatusLine: 100
错误,因为这不是格式正确的HTTP响应。
是否有其他方法可以获取网址并获取原始内容,而无需尝试解析响应?
由于
答案 0 :(得分:1)
在这种情况下,您需要做的是send a raw HTTP request using sockets
在这种情况下,您需要使用socket
python模块进行一些低级网络编程。 (网络套接字实际上会返回服务器as it as
发送的所有信息,因此您可以根据需要解释响应。例如,HTTP协议根据标准HTTP头解释响应 - GET,POST, HEAD等。高级模块urllib
隐藏了您的头信息,只返回数据。)
您还需要了解有关HTTP标头的一些基本信息。对于您的情况,您只需要了解GET
HTTP请求。在此处查看其定义 - 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请求并阅读它回复了。您也可以参考此unclear question on SO。
(您可以通过Google python socket http
获取更多示例。)
(提示:我不是Java粉丝,但是如果你在python下找不到关于这个主题的足够令人信服的例子,试着在Java下找到它,然后相应地将它翻译成python。)
答案 1 :(得分: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/'))
HTH!
修改:您可能需要根据相关的网络服务器调整您在请求中添加的内容。 Guanidene的优秀答案提供了一些资源来指导您走上这条道路。
答案 2 :(得分:0)
urllib.urlretrieve('http://google.com/abc.jpg', 'abc.jpg')