什么是http和https協(xié)議:
HTTP協(xié)議:全稱是HyperText Transfer Protocol测萎,中文意思是超文本傳輸協(xié)議殉疼,是一種發(fā)布和接收HTML頁面的方法望拖。服務(wù)器端口號是80端口浩村。 HTTPS協(xié)議:是HTTP協(xié)議的加密版本,在HTTP下加入了SSL層。服務(wù)器端口號是443端口茄袖。
在瀏覽器中發(fā)送一個http請求的過程:
當用戶在瀏覽器的地址欄中輸入一個URL并按回車鍵之后访雪,瀏覽器會向HTTP服務(wù)器發(fā)送HTTP請求。HTTP請求主要分為“Get”和“Post”兩種方法遗嗽。
當我們在瀏覽器輸入URL?http://www.baidu.com?的時候粘我,瀏覽器發(fā)送一個Request請求去獲取?http://www.baidu.com?的html文件,服務(wù)器把Response文件對象發(fā)送回給瀏覽器痹换。
瀏覽器分析Response中的 HTML征字,發(fā)現(xiàn)其中引用了很多其他文件都弹,比如Images文件,CSS文件匙姜,JS文件缔杉。 瀏覽器會自動再次發(fā)送Request去獲取圖片,CSS文件搁料,或者JS文件或详。
當所有的文件都下載成功后,網(wǎng)頁會根據(jù)HTML語法結(jié)構(gòu)郭计,完整的顯示出來了霸琴。
url詳解:
URL是Uniform Resource Locator的簡寫,統(tǒng)一資源定位符昭伸。 一個URL由以下幾部分組成:
? ? scheme://host:port/path/?query-string=xxx#anchor
scheme:代表的是訪問的協(xié)議梧乘,一般為http或者https以及ftp等。
host:主機名庐杨,域名选调,比如www.baidu.com。
port:端口號灵份。當你訪問一個網(wǎng)站的時候仁堪,瀏覽器默認使用80端口。
path:查找路徑填渠。比如:www.reibang.com/trending/now弦聂,后面的trending/now就是path。
query-string:查詢字符串氛什,比如:www.baidu.com/s?wd=python莺葫,后面的wd=python就是查詢字符串。
anchor:錨點枪眉,后臺一般不用管捺檬,前端用來做頁面定位的。
在瀏覽器中請求一個url贸铜,瀏覽器會對這個url進行一個編碼堡纬。除英文字母,數(shù)字和部分符號外萨脑,其他的全部使用百分號+十六進制碼值進行編碼隐轩。
常用的請求方法:
在Http協(xié)議中,定義了八種請求方法渤早。這里介紹兩種常用的請求方法职车,分別是get請求和post請求。
get請求:一般情況下,只從服務(wù)器獲取數(shù)據(jù)下來悴灵,并不會對服務(wù)器資源產(chǎn)生任何影響的時候會使用get請求扛芽。
post請求:向服務(wù)器發(fā)送數(shù)據(jù)(登錄)、上傳文件等积瞒,會對服務(wù)器資源產(chǎn)生影響的時候會使用post請求川尖。 以上是在網(wǎng)站開發(fā)中常用的兩種方法。并且一般情況下都會遵循使用的原則茫孔。但是有的網(wǎng)站和服務(wù)器為了做反爬蟲機制叮喳,也經(jīng)常會不按常理出牌,有可能一個應該使用get方法的請求就一定要改成post請求缰贝,這個要視情況而定馍悟。
請求頭常見參數(shù):
在http協(xié)議中,向服務(wù)器發(fā)送一個請求剩晴,數(shù)據(jù)分為三部分锣咒,第一個是把數(shù)據(jù)放在url中,第二個是把數(shù)據(jù)放在body中(在post請求中)赞弥,第三個就是把數(shù)據(jù)放在head中毅整。這里介紹在網(wǎng)絡(luò)爬蟲中經(jīng)常會用到的一些請求頭參數(shù):
User-Agent:瀏覽器名稱。這個在網(wǎng)絡(luò)爬蟲中經(jīng)常會被使用到绽左。請求一個網(wǎng)頁的時候悼嫉,服務(wù)器通過這個參數(shù)就可以知道這個請求是由哪種瀏覽器發(fā)送的。如果我們是通過爬蟲發(fā)送請求妇菱,那么我們的User-Agent就是Python承粤,這對于那些有反爬蟲機制的網(wǎng)站來說,可以輕易的判斷你這個請求是爬蟲闯团。因此我們要經(jīng)常設(shè)置這個值為一些瀏覽器的值,來偽裝我們的爬蟲仙粱。
Referer:表明當前這個請求是從哪個url過來的房交。這個一般也可以用來做反爬蟲技術(shù)。如果不是從指定頁面過來的伐割,那么就不做相關(guān)的響應候味。
Cookie:http協(xié)議是無狀態(tài)的。也就是同一個人發(fā)送了兩次請求隔心,服務(wù)器沒有能力知道這兩個請求是否來自同一個人白群。因此這時候就用cookie來做標識。一般如果想要做登錄后才能訪問的網(wǎng)站硬霍,那么就需要發(fā)送cookie信息了帜慢。
常見響應狀態(tài)碼:
200:請求正常,服務(wù)器正常的返回數(shù)據(jù)。
301:永久重定向粱玲。比如在訪問www.jingdong.com的時候會重定向到www.jd.com躬柬。
302:臨時重定向抽减。比如在訪問一個需要登錄的頁面的時候允青,而此時沒有登錄,那么就會重定向到登錄頁面卵沉。
400:請求的url在服務(wù)器上找不到颠锉。換句話說就是請求url錯誤。
403:服務(wù)器拒絕訪問史汗,權(quán)限不夠琼掠。
500:服務(wù)器內(nèi)部錯誤⊙桶欤可能是服務(wù)器出現(xiàn)bug了眉枕。
urllib庫
urllib庫是Python中一個最基本的網(wǎng)絡(luò)請求庫×可以模擬瀏覽器的行為速挑,向指定的服務(wù)器發(fā)送一個請求,并可以保存服務(wù)器返回的數(shù)據(jù)副硅。
urlopen函數(shù):
在Python3的urllib庫中姥宝,所有和網(wǎng)絡(luò)請求相關(guān)的方法,都被集到urllib.request模塊下面了恐疲,以先來看下urlopen函數(shù)基本的使用:
fromurllibimportrequestresp = request.urlopen('http://www.baidu.com')print(resp.read())
實際上腊满,使用瀏覽器訪問百度,右鍵查看源代碼培己。你會發(fā)現(xiàn)碳蛋,跟我們剛才打印出來的數(shù)據(jù)是一模一樣的。也就是說省咨,上面的三行代碼就已經(jīng)幫我們把百度的首頁的全部代碼爬下來了肃弟。一個基本的url請求對應的python代碼真的非常簡單。
以下對urlopen函數(shù)的進行詳細講解:
url:請求的url零蓉。
data:請求的data笤受,如果設(shè)置了這個值,那么將變成post請求敌蜂。
返回值:返回值是一個http.client.HTTPResponse對象箩兽,這個對象是一個類文件句柄對象。有read(size)章喉、readline汗贫、readlines以及getcode等方法身坐。
urlretrieve函數(shù):
這個函數(shù)可以方便的將網(wǎng)頁上的一個文件保存到本地。以下代碼可以非常方便的將百度的首頁下載到本地:
fromurllibimportrequestrequest.urlretrieve('http://www.baidu.com/','baidu.html')
urlencode函數(shù):
用瀏覽器發(fā)送請求的時候芳绩,如果url中包含了中文或者其他特殊字符掀亥,那么瀏覽器會自動的給我們進行編碼。而如果使用代碼發(fā)送請求妥色,那么就必須手動的進行編碼搪花,這時候就應該使用urlencode函數(shù)來實現(xiàn)。urlencode可以把字典數(shù)據(jù)轉(zhuǎn)換為URL編碼的數(shù)據(jù)嘹害。示例代碼如下:
fromurllibimportparsedata = {'name':'爬蟲基礎(chǔ)','greet':'hello world','age':100}qs = parse.urlencode(data)print(qs)
parse_qs函數(shù):
可以將經(jīng)過編碼后的url參數(shù)進行解碼撮竿。示例代碼如下:
fromurllibimportparseqs ="name=%E7%88%AC%E8%99%AB%E5%9F%BA%E7%A1%80&greet=hello+world&age=100"print(parse.parse_qs(qs))
urlparse和urlsplit:
有時候拿到一個url,想要對這個url中的各個組成部分進行分割笔呀,那么這時候就可以使用urlparse或者是urlsplit來進行分割幢踏。示例代碼如下:
fromurllibimportrequest,parseurl ='http://www.baidu.com/s?username=zhiliao'result = parse.urlsplit(url)# result = parse.urlparse(url)print('scheme:',result.scheme)print('netloc:',result.netloc)print('path:',result.path)print('query:',result.query)
urlparse和urlsplit基本上是一模一樣的。唯一不一樣的地方是许师,urlparse里面多了一個params屬性房蝉,而urlsplit沒有這個params屬性。比如有一個url為:url = 'http://www.baidu.com/s;hello?wd=python&username=abc#1'微渠,
那么urlparse可以獲取到hello搭幻,而urlsplit不可以獲取到。url中的params也用得比較少逞盆。
request.Request類:
如果想要在請求的時候增加一些請求頭檀蹋,那么就必須使用request.Request類來實現(xiàn)。比如要增加一個User-Agent云芦,示例代碼如下:
fromurllibimportrequestheaders = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}req = request.Request("http://www.baidu.com/",headers=headers)resp = request.urlopen(req)print(resp.read())