摘要:結(jié)果總是重定向,狀態(tài)碼找了好久都不知道什么原因,而且直接在瀏覽器網(wǎng)址欄輸入網(wǎng)址,用抓包也沒(méi)有抓到狀態(tài)為的包。其實(shí)狀態(tài)碼的時(shí)候應(yīng)答部分的可以觀察到,但是一個(gè)太不顯眼了所以我沒(méi)有注意到,導(dǎo)致卡了很久接下來(lái)只要知道如何發(fā)送請(qǐng)求就好了。
這是個(gè)在寫(xiě)計(jì)算機(jī)網(wǎng)絡(luò)課設(shè)的時(shí)候碰到的問(wèn)題,卡了我一天,所以總結(jié)一下。
其實(shí)在之前就有用requests寫(xiě)過(guò)python爬蟲(chóng),但是計(jì)算機(jī)網(wǎng)絡(luò)要求更底層的實(shí)現(xiàn),剛好我看到了[這篇文章]1結(jié)果發(fā)現(xiàn)他就是用socket來(lái)實(shí)現(xiàn)的請(qǐng)求,所以就學(xué)習(xí)了。
本來(lái)也覺(jué)得應(yīng)該不難,畢竟就是建立tcp連接。原網(wǎng)站的例子如下:
def fetch(url): sock = socket.socket() # 建立socket sock.connect(("xkcd.com", 80)) # 遠(yuǎn)程連接 request = "GET {} HTTP/1.0 Host: xkcd.com ".format(url) # 構(gòu)建請(qǐng)求 sock.send(request.encode("ascii")) # 向socket發(fā)送數(shù)據(jù) response = b"" chunk = sock.recv(4096) # 從socket接收數(shù)據(jù) while chunk: response += chunk chunk = sock.recv(4096) # Page is now downloaded. links = parse_links(response) q.add(links)
我選擇爬取的網(wǎng)站是鏈家,當(dāng)然也看了很多其他例子,還用fiddler抓包,把headers整個(gè)放了上去,首先是參考了這個(gè)文章,寫(xiě)出如下代碼。
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 """)
結(jié)果總是報(bào)400(Bad Request),這個(gè)地方卡了很久,最后解決辦法是一條一條發(fā)送,每一條后面加 。
sock = socket.socket() sock.connect(("zh.lianjia.com", 80)) sock.send("GET /ershoufang/ HTTP/1.1 ".encode()) sock.send("Host: zh.lianjia.com ".encode()) sock.send("Connection: keep-alive ".encode()) sock.send("Cache-Control: no-cache ".encode()) sock.send("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 ".encode()) sock.send("Upgrade-Insecure-Requests: 1 ".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 ".encode()) sock.send("Accept-Encoding: gzip, deflate, br ".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 ".encode())
結(jié)果總是重定向,狀態(tài)碼301!找了好久都不知道什么原因,而且直接在瀏覽器網(wǎng)址欄輸入網(wǎng)址,用fiddler抓包也沒(méi)有抓到狀態(tài)為301的包。最后使用fiddler的composer輸入http://zh.lianjia.com/ershoufang 就抓到了301和200,其中200的地址就是https://zh.lianjia.com/ershoufang,如下圖所示。
這下知道原因了,是http和https的區(qū)別。(其實(shí)301狀態(tài)碼的時(shí)候應(yīng)答部分的Location可以觀察到,但是一個(gè)s太不顯眼了所以我沒(méi)有注意到,導(dǎo)致卡了很久)
接下來(lái)只要知道如何發(fā)送https請(qǐng)求就好了。下面是代碼,主要是更改建立socket和連接的部分。注意端口號(hào)為443。參考文章在這里
sock = ssl.wrap_socket(socket.socket()) sock.connect(("zh.lianjia.com", 443))
感覺(jué)自己很多地方了解的不夠深入,暫時(shí)學(xué)校也沒(méi)有講到應(yīng)用層。到時(shí)候再研究研究,如有錯(cuò)漏歡迎指出。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/41683.html
摘要:我們以訪問(wèn)百度主頁(yè)為案例,使用發(fā)送請(qǐng)求?;谶M(jìn)行編程在于請(qǐng)求參數(shù)的可控性更好,但是難度相應(yīng)就更大了。以上發(fā)送的數(shù)據(jù)是直接從抓包器里面復(fù)制的。 我們以訪問(wèn)百度主頁(yè)為案例,使用socket發(fā)送http請(qǐng)求。 import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect((www.baidu.com,80...
摘要:對(duì)于網(wǎng)絡(luò)編程來(lái)說(shuō),免不了要用到模塊。表示另一端的地址。以上主要是針對(duì)流數(shù)據(jù)的編程。對(duì)于協(xié)議的數(shù)據(jù),處理略有不同。通過(guò)傳入對(duì)象調(diào)用來(lái)監(jiān)聽(tīng)對(duì)象的文件描述符,一旦發(fā)現(xiàn)對(duì)象就緒,就通知應(yīng)用程序進(jìn)行相應(yīng)的讀寫(xiě)操作。 對(duì)于python網(wǎng)絡(luò)編程來(lái)說(shuō),免不了要用到socket模塊。下面分享一下個(gè)人對(duì)python socket的一些理解。 socket編程步驟 服務(wù)端創(chuàng)建一個(gè)socket,綁定地址和端...
摘要:當(dāng)一個(gè)客戶端連接時(shí),它將返回一個(gè)新的對(duì)象,對(duì)象中有表示當(dāng)前連接的和一個(gè)由主機(jī)端口號(hào)組成的連接的元組,更多關(guān)于元組值的內(nèi)容可以查看地址族一節(jié)中的詳情這里必須要明白我們通過(guò)調(diào)用方法擁有了一個(gè)新的對(duì)象。 博客原文: https://keelii.com/2018/09/24/socket-programming-in-python/ 說(shuō)明 本書(shū)翻譯自 realpython 網(wǎng)站上的文章教程 ...
摘要:前言最近看了一些同學(xué)的面經(jīng),發(fā)現(xiàn)無(wú)論什么技術(shù)崗位,還是會(huì)問(wèn)到和的區(qū)別,而搜索出來(lái)的答案并不能讓我們裝得一手好逼,那就讓我們從報(bào)文的角度來(lái)擼一波,從而搞明白他們的區(qū)別。所以,和分開(kāi)發(fā)送是部分瀏覽器或框架的請(qǐng)求方法,不屬于必然行為。 1 前言 最近看了一些同學(xué)的面經(jīng),發(fā)現(xiàn)無(wú)論什么技術(shù)崗位,還是會(huì)問(wèn)到 get 和 post 的區(qū)別,而搜索出來(lái)的答案并不能讓我們裝得一手好逼,那就讓我們從 HT...
閱讀 3324·2021-09-22 15:58
閱讀 1786·2019-08-30 14:17
閱讀 1779·2019-08-28 18:05
閱讀 1572·2019-08-26 13:33
閱讀 742·2019-08-26 12:20
閱讀 670·2019-08-26 12:18
閱讀 3261·2019-08-26 11:59
閱讀 1464·2019-08-26 10:36