Heim  >  Artikel  >  Backend-Entwicklung  >  Verwenden Sie den Python-Socket, um die HTTP(s)-Anfragemethode zu senden

Verwenden Sie den Python-Socket, um die HTTP(s)-Anfragemethode zu senden

不言
不言Original
2018-05-07 11:54:244318Durchsuche

Dieser Artikel führt Sie hauptsächlich in die relevanten Informationen zur Verwendung von Python-Sockets zum Senden von HTTP(s)-Anfragen ein. Der Artikel stellt es ausführlich anhand von Beispielcodes vor. Es hat einen gewissen Referenzwert für das Erlernen oder Verwenden von Python ist notwendig Freunde, schauen wir es uns gemeinsam an

Vorwort

Dies ist ein Problem, auf das ich gestoßen bin, als ich einen Computernetzwerkkurs geschrieben habe Design. Ich habe einen Tag Zeit, um es zusammenzufassen.

Tatsächlich habe ich schon einmal einen Python-Crawler geschrieben, der Anfragen verwendet, aber das Computernetzwerk erfordert eine Implementierung auf niedrigerer Ebene. Ich habe gerade [diesen Artikel]1 gesehen und festgestellt, dass er Sockets verwendet, um Anfragen zu implementieren. also habe ich gelernt.

Ich dachte zunächst, dass es nicht schwierig sein sollte, schließlich geht es nur darum, eine TCP-Verbindung herzustellen.

Ein Beispiel der ursprünglichen Website ist wie folgt:

 def fetch(url):
 sock = socket.socket() # 建立socket
 sock.connect(('xkcd.com', 80)) # 远程连接
 request = 'GET {} HTTP/1.0\r\nHost: xkcd.com\r\n\r\n'.format(url) # 构建请求
 sock.send(request.encode('ascii')) # 向socket发送数据
 response = b'' 
 chunk = sock.recv(4096) # 从socket接收数据
 while chunk:
 response += chunk
 chunk = sock.recv(4096)

 # Page is now downloaded.
 links = parse_links(response)
 q.add(links)

Die Website, die ich zum Crawlen ausgewählt habe, ist Lianjia, Und natürlich habe ich mir auch viele andere Beispiele angesehen, in denen Fiddler auch zum Erfassen von Paketen und zum Einfügen der gesamten Header verwendet wird. Lesen Sie zunächst diesen Artikel: https://segmentfault.com/a/1190000005126160 🎜>

Python über Socket HTTP-Anfrage senden

Wir nehmen den Besuch der Baidu-Homepage als Beispiel und verwenden Socket zum Senden einer HTTP-Anfrage.


import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('www.baidu.com',80))
s.send('''GET https://www.baidu.com/ HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Accept-Language: zh-CN,zh;q=0.8

''')

buf=s.recv(1024)
while len(buf):
print buf
buf = s.recv(1024)

Die auf Socket basierende HTTP-Programmierung besteht darin, dass die Anforderungsparameter besser kontrollierbar sind, die Schwierigkeit jedoch entsprechend größer ist. Die oben gesendeten Daten werden direkt vom Fiddler Packet Capturer kopiert.

Schreiben Sie auf der Grundlage des oben Gesagten den folgenden Code:

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('www.baidu.com',80))
s.send('''GET / HTTP/1.1
Host: zh.lianjia.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: https://www.baidu.com/link?url=4J5Kx--GLdLFESJhkfRePU8Ac_0agnTcOtB-b3kfnX8VNdZ_6TPqOyJGKVXkTczg&ck=6140.3.83.296.315.287.208.155&shh=www.baidu.com&sht=94886267_hao_pg&wd=&eqid=af98b98700060b77000000065aef0524
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-CA;q=0.8,en;q=0.7
Cookie: lianjia_uuid=ce61c41c-25b0-46d6-a0a0-d57a75ee8706; UM_distinctid=1631f588055f9-0286722badd3ec-b34356b-1fa400-1631f58805657f; _ga=GA1.2.43397143.1525239286; _smt_uid=5ae94e02.558be516; _jzqx=1.1525248800.1525335927.1.jzqsr=zh%2Elianjia%2Ecom|jzqct=/ershoufang/xiangzhouqu/.-; _jzqc=1; _jzqckmp=1; _gid=GA1.2.1028411676.1525594529; select_city=440400; all-lj=c60bf575348a3bc08fb27ee73be8c666; _qzjc=1; CNZZDATA1254525948=963210960-1525238218-https%253A%252F%252Fwww.lianjia.com%252F%7C1525608956; CNZZDATA1255633284=1054798284-1525238580-https%253A%252F%252Fwww.lianjia.com%252F%7C1525608969; lianjia_ssid=c046ddb3-3e66-4809-998a-52ade335fdfc; _qzja=1.1070225156.1525239298260.1525603274282.1525613866775.1525609113492.1525613866775.0.0.0.92.9; _qzjto=29.3.0; _jzqa=1.3750161754444366000.1525239284.1525603274.1525613867.9; _jzqy=1.1525239284.1525613867.3.jzqsr=baidu.jzqsr=baidu; Hm_lvt_9152f8221cb6243a53c83b956842be8a=1525607433,1525607626,1525609113,1525613867; Hm_lpvt_9152f8221cb6243a53c83b956842be8a=1525613867; _qzjb=1.1525613866775.1.0.0.0; _jzqb=1.1.10.1525613867.1; CNZZDATA1255604082=964175865-1525237915-https%253A%252F%252Fwww.lianjia.com%252F%7C1525612833
''')

Das Ergebnis wird immer als

gemeldet Die endgültige Lösung wird nacheinander gesendet, gefolgt von rn. 400(Bad Request)

 sock = socket.socket()
 sock.connect(('zh.lianjia.com', 80))
 sock.send('GET /ershoufang/ HTTP/1.1\r\n'.encode())
 sock.send('Host: zh.lianjia.com\r\n'.encode())
 sock.send('Connection: keep-alive\r\n'.encode())
 sock.send('Cache-Control: no-cache\r\n'.encode())
 sock.send('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n'.encode())
 sock.send('Upgrade-Insecure-Requests: 1\r\n'.encode())
 sock.send('User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36\r\n'.encode())
 sock.send('Accept-Encoding: gzip, deflate, br\r\n'.encode())
 sock.send('Cookie: lianjia_uuid=ce61c41c-25b0-46d6-a0a0-d57a75ee8706; UM_distinctid=1631f588055f9-0286722badd3ec-b34356b-1fa400-1631f58805657f; _ga=GA1.2.43397143.1525239286; _smt_uid=5ae94e02.558be516; _jzqx=1.1525248800.1525335927.1.jzqsr=zh%2Elianjia%2Ecom|jzqct=/ershoufang/xiangzhouqu/.-; _jzqc=1; _jzqy=1.1525239284.1525594526.2.jzqsr=baidu.jzqsr=baidu|jzqct=%E9%93%BE%E5%AE%B6; _jzqckmp=1; _gid=GA1.2.1028411676.1525594529; Hm_lvt_9152f8221cb6243a53c83b956842be8a=1525594526,1525594536,1525594804,1525595210; select_city=440400; all-lj=c60bf575348a3bc08fb27ee73be8c666; _qzjc=1; lianjia_ssid=99306d63-8ee5-a53c-a740-2d3021f3db2f; CNZZDATA1255604082=964175865-1525237915-https%253A%252F%252Fwww.lianjia.com%252F%7C1525602095; _jzqa=1.3750161754444366000.1525239284.1525594526.1525603274.8; CNZZDATA1254525948=963210960-1525238218-https%253A%252F%252Fwww.lianjia.com%252F%7C1525603556; CNZZDATA1255633284=1054798284-1525238580-https%253A%252F%252Fwww.lianjia.com%252F%7C1525603557; Hm_lpvt_9152f8221cb6243a53c83b956842be8a=1525606057; _jzqb=1.9.10.1525603274.1; _qzja=1.1070225156.1525239298260.1525597069547.1525603274282.1525605398368.1525606071025.0.0.0.86.8; _qzjb=1.1525603274282.9.0.0.0; _qzjto=23.2.0\r\n\r\n'.encode())

Das Ergebnis wird immer mit Statuscode 301 weitergeleitet! Ich habe schon lange danach gesucht, weiß aber immer noch nicht, warum. Außerdem habe ich die URL direkt in die URL-Leiste des Browsers eingegeben und Fiddler zum Erfassen der Pakete verwendet, aber es wurden keine Pakete mit dem Status 301 erfasst. Geben Sie schließlich mit Fiddler's Composer http://zh.lianjia.com/ershoufang ein und fangen Sie 301 und 200 ein. Die Adresse von 200 lautet https://zh.lianjia.com/ershoufang, wie in der folgenden Abbildung dargestellt.

Jetzt kenne ich den Grund, es ist der Unterschied zwischen http und https. (Tatsächlich kann man den Ort im Antwortteil im 301-Statuscode beobachten, aber das s ist zu unauffällig, sodass ich es nicht bemerkt habe, was dazu führte, dass es lange hängen blieb)

Der nächste Schritt besteht darin, zu wissen, wie man eine https-Anfrage sendet. Das Folgende ist der Code, der hauptsächlich den Teil ändert, der den Socket herstellt und eine Verbindung herstellt. Beachten Sie, dass die Portnummer 443 ist. Der Referenzartikel ist hier

 sock = ssl.wrap_socket(socket.socket())
 sock.connect(('zh.lianjia.com', 443))

Ich habe das Gefühl, dass ich es an vielen Stellen nicht tief genug verstehe und die Schule hat noch nicht über die Anwendungsschicht gesprochen . Ich werde es zu gegebener Zeit noch einmal durchgehen und bitte auf etwaige Fehler oder Auslassungen hinweisen.

Verwandte Empfehlungen:


Beispiel für die Verwendung von Python zur Ausgabe von PDF in TXT

Verwendung von Python zur dynamischen Ausführung von Shell-Skripten Übertragen Sie sie. Beteiligt an der grundlegenden Verwendung des Unterprozesses

Das obige ist der detaillierte Inhalt vonVerwenden Sie den Python-Socket, um die HTTP(s)-Anfragemethode zu senden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn