0

URLをフェッチする必要があるPythonで小さなスクリプトを作成したいと思います。ただし、サーバーは一種のくだらないものであり、ヘッダーなしで純粋なASCIIに応答します。

私が試してみると:

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

http.client.BadStatusLine: 100これは適切にフォーマットされたHTTP応答ではないため、エラーが発生します。

応答を解析しようとせずに、URLをフェッチして生のコンテンツを取得する別の方法はありますか?

ありがとう

4

3 に答える 3

1

この場合に行う必要があるのはですsend a raw HTTP request using sockets。この場合、Pythonモジュール
を使用して低レベルのネットワークプログラミングを少し行う必要があります。socket(ネットワークソケットは実際にはサーバーから送信されたすべての情報を返す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リクエストを送信する方法を示しています。返信を読み返してください。SOに関するこの不明確な質問を参照することもできます。

python socket http(より多くの例を取得するために グーグルすることができます。)

(ヒント:私はJavaファンではありませんが、それでも、Pythonでこのトピックに関する説得力のある例が十分に見つからない場合は、Javaで見つけてみて、それに応じてPythonに翻訳してください。)

于 2012-04-11T15:41:13.357 に答える
1

もう少し情報がなければ、直接の質問に答えることは困難です。問題の(Web)サーバーがどのように壊れているかを正確に知らない。

socket そうは言っても、たとえば、少し低レベルのものを使用してみるとよいでしょう。これが1つの方法です(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!

編集:問題のWebサーバーによっては、リクエストに入力する内容を調整する必要がある場合があります。Guanideneの優れた回答は、その道を案内するためのいくつかのリソースを提供します。

于 2012-04-11T15:44:06.290 に答える
0
urllib.urlretrieve('http://google.com/abc.jpg', 'abc.jpg')
于 2012-04-11T14:25:05.327 に答える