日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

python-爬蟲-網絡請求(二)

系統 1813 0

網絡請求

urlopen函數用法

urllib庫

urllib庫是python中一個最基本的網絡請求庫。可以模擬瀏覽器的行為,向指定的服務器發送一個請求,并可以保存服務器返回的數據

urlopen函數

在python3的urllib庫中,所有和網絡請求相關的方法都被集成到urllib.request模塊下面了,下面先看下urlopen函數基本使用:

            
              
                from
              
               urllib 
              
                import
              
               request
	resp 
              
                =
              
               request
              
                .
              
              urlopen
              
                (
              
              
                'http://www.baidu.com'
              
              
                )
              
              
                print
              
              
                (
              
              resp
              
                .
              
              read
              
                (
              
              
                )
              
              
                )
              
            
          

實際上,使用瀏覽器訪問百度,右鍵查看源代碼。就會發現,打印處理的內容就是和請求的內容一摸一樣的,也就是說,上面的三行代碼已經幫我們將百度首頁的內容全部爬下來了
這里對urlopen函數進行詳細講解:

  1. url:請求的url
  2. data:請求的data,如果設置了這個值,那么請求將會變成post請求
  3. 返回值:返回值是一個http.client.HTTPResponse對象,這個對象是一個類文件句柄對象有read(size)、readline、readlines以及getcode等方法

urlretrieve函數

這個函數可以方便的將網頁上的一個文件保存到本地。以下代碼可以非常方便的將百度的首頁下載到本地

            
              
                from
              
               urllib 
              
                import
              
               request
	request
              
                .
              
              urlretrieve
              
                (
              
              
                'http://www.baidu.com/'
              
              
                ,
              
              
                'baidu.html'
              
              
                )
              
            
          

使用這個函數,可以方便我們將圖片或者其他的內容下載到本地

urlencode函數

用瀏覽器發送請求的時候,如果url中包含了中文或者其他特殊符號,那么瀏覽器會自動給我們進行編碼,而如果使用代碼發送請求,那么就必須手動進行編碼,這時候就應該使用urlencode函數來實現,urlencode可以把字典數據轉換為URL編碼的數據,示例代碼如下:

            
              
                from
              
               urllib 
              
                import
              
               parse
	data 
              
                =
              
              
                {
              
              
                'name'
              
              
                :
              
              
                '爬蟲基礎'
              
              
                ,
              
              
                'greet'
              
              
                :
              
              
                'hello world'
              
              
                ,
              
              
                'age'
              
              
                :
              
              
                100
              
              
                }
              
              
	result 
              
                =
              
               parse
              
                .
              
              urlencode
              
                (
              
              data
              
                )
              
              
                print
              
              
                (
              
              result
              
                )
              
              
	name
              
                =
              
              
                %
              
              E7
              
                %
              
              
                88
              
              
                %
              
              AC
              
                %
              
              E8
              
                %
              
              
                99
              
              
                %
              
              AB
              
                %
              
              E5
              
                %
              
              
                9F
              
              
                %
              
              BA
              
                %
              
              E7
              
                %
              
              A1
              
                %
              
              
                80
              
              
                &
              
              greet
              
                =
              
              hello
              
                +
              
              world
              
                &
              
              age
              
                =
              
              
                100
              
            
          

parse_qs函數

可以將經過編碼后的url參數進行解碼(這個是配合上面urlencode函數配合使用的),示例代碼如下:

            
              
                from
              
               urllib 
              
                import
              
               parse

	params 
              
                =
              
              
                {
              
              
                'name'
              
              
                :
              
              
                '張三'
              
              
                ,
              
              
                'age'
              
              
                :
              
              
                18
              
              
                ,
              
              
                'greet'
              
              
                :
              
              
                'hello world'
              
              
                }
              
              
	qs 
              
                =
              
               parse
              
                .
              
              urlencode
              
                (
              
              params
              
                )
              
              
                print
              
              
                (
              
              qs
              
                )
              
              

	result 
              
                =
              
               parse
              
                .
              
              parse_qs
              
                (
              
              qs
              
                )
              
              
                print
              
              
                (
              
              result
              
                )
              
              

	name
              
                =
              
              
                %
              
              E5
              
                %
              
              BC
              
                %
              
              A0
              
                %
              
              E4
              
                %
              
              B8
              
                %
              
              
                89
              
              
                &
              
              age
              
                =
              
              
                18
              
              
                &
              
              greet
              
                =
              
              hello
              
                +
              
              world
	
              
                {
              
              
                'name'
              
              
                :
              
              
                [
              
              
                '張三'
              
              
                ]
              
              
                ,
              
              
                'age'
              
              
                :
              
              
                [
              
              
                '18'
              
              
                ]
              
              
                ,
              
              
                'greet'
              
              
                :
              
              
                [
              
              
                'hello world'
              
              
                ]
              
              
                }
              
            
          

urlparse和urlsplit

有時候拿到一個url,想要對這個url中的各個組成部分進行分割,那么這時候就可以使用urlparse或者urlsplit來進行分割
首先來看下urlparse

            
              
                from
              
               urllib 
              
                import
              
               parse
	
	url 
              
                =
              
              
                'http://www.baidu.com/s?wb=python&username=abc#1'
              
              
	result 
              
                =
              
               parse
              
                .
              
              urlparse
              
                (
              
              url
              
                )
              
              
                print
              
              
                (
              
              result
              
                )
              
              
	
	ParseResult
              
                (
              
              scheme
              
                =
              
              
                'http'
              
              
                ,
              
               netloc
              
                =
              
              
                'www.baidu.com'
              
              
                ,
              
               path
              
                =
              
              
                '/s'
              
              
                ,
              
               params
              
                =
              
              
                ''
              
              
                ,
              
               query
              
                =
              
              
                'wb=python&username=abc'
              
              
                ,
              
               fragment
              
                =
              
              
                '1'
              
              
                )
              
            
          

如果僅僅只想獲取中間某一個內容,可以使用如下的方式來進行獲取

            
              
                print
              
              
                (
              
              result
              
                .
              
              scheme
              
                )
              
              
	http

            
          

其次來看下urlsplit

            
              	url 
              
                =
              
              
                'http://www.baidu.com/s?wb=python&username=abc#1'
              
              
	result 
              
                =
              
               parse
              
                .
              
              urlsplit
              
                (
              
              url
              
                )
              
              
                print
              
              
                (
              
              result
              
                )
              
              
	SplitResult
              
                (
              
              scheme
              
                =
              
              
                'http'
              
              
                ,
              
               netloc
              
                =
              
              
                'www.baidu.com'
              
              
                ,
              
               path
              
                =
              
              
                '/s'
              
              
                ,
              
               query
              
                =
              
              
                'wb=python&username=abc'
              
              
                ,
              
               fragment
              
                =
              
              
                '1'
              
              
                )
              
            
          

對比可以發現,在使用urlsplit的時候,中間缺少了一個params的參數,這里的params在現在的爬蟲中間用到的比較少,這里獲取的內容就是 ;和?之間的內容,如下所示

            
              
                from
              
               urllib 
              
                import
              
               parse
	
	url 
              
                =
              
              
                'http://www.baidu.com/s;hello?wb=python&username=abc#1'
              
              
	result 
              
                =
              
               parse
              
                .
              
              urlparse
              
                (
              
              url
              
                )
              
              
                print
              
              
                (
              
              result
              
                )
              
              
	ParseResult
              
                (
              
              scheme
              
                =
              
              
                'http'
              
              
                ,
              
               netloc
              
                =
              
              
                'www.baidu.com'
              
              
                ,
              
               path
              
                =
              
              
                '/s'
              
              
                ,
              
               params
              
                =
              
              
                'hello'
              
              
                ,
              
               query
              
                =
              
              
                'wb=python&username=abc'
              
              
                ,
              
               fragment
              
                =
              
              
                '1'
              
              
                )
              
            
          

通常情況下,使用urlparse和urlsplit是一樣的,唯一不一樣的地方就是,urlparse中間多一個params屬性,而urlsplit沒有這個屬性

request.Request類

如果想要在請求的時候增加一些請求頭,那么就必須使用request.Request來實現。如果要增加一個User-Agent

            
              
                from
              
               urllib 
              
                import
              
               request
	
	url 
              
                =
              
              
                'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput='
              
              
                # resp = request.urlopen(url)
              
              
                # print(resp.read())
              
              
	
	headers 
              
                =
              
              
                {
              
              
                'User-Agent'
              
              
                :
              
              
                'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
              
              
                }
              
              
	
	req 
              
                =
              
               request
              
                .
              
              Request
              
                (
              
              url
              
                ,
              
              headers
              
                =
              
              headers
              
                )
              
              
	resp 
              
                =
              
               request
              
                .
              
              urlopen
              
                (
              
              req
              
                )
              
              
                print
              
              
                (
              
              resp
              
                .
              
              read
              
                (
              
              
                )
              
              
                )
              
            
          

在上面的代碼中,如果想要給請求的url加上一個請求頭的話,就需要使用request.Request這個方式將請求的內容進行一個封裝,這里封裝的請求頭是User-Agent這個請求頭,這里將這里面的內容寫上瀏覽器的標識;這里需要注意,這里封裝好了之后,是還并沒有發起請求的,最后還是調用的request.urlopen方法發起請求的
注意:這里的這個request.Request方法除了能夠傳遞User-Agent外,還能夠傳遞data和method
如下:
python-爬蟲-網絡請求(二)_第1張圖片

ProxyHandler處理器(代理設置)

很多網站會檢測某一段時間某個ip的訪問次數(通過流量統計,系統日志等),如果訪問次數多的不像正常人,就會禁止這個ip的訪問,所有我們可以設置一些代理服務器,每隔一段時間換一個代理,就算ip被禁止,依然可以換個ip繼續爬取
urllib中通過ProxyHandler來設置使用代理服務器,下面代碼說明如果使用自定義opener來使用代理

            
              
                from
              
               urllib 
              
                import
              
               request
	
	
              
                # 未使用代理
              
              
                # url = 'http://httpbin.org/ip'
              
              
                #
              
              
                # resp = request.urlopen(url)
              
              
                # print(resp.read())
              
              
                # -----------------------
              
              
                # 使用代理的
              
              
	url 
              
                =
              
              
                'http://httpbin.org/ip'
              
              
                # 1、使用ProxyHandler,傳入代理構建一個handler
              
              
	handler 
              
                =
              
               request
              
                .
              
              ProxyHandler
              
                (
              
              
                {
              
              
                'http'
              
              
                :
              
              
                '125.110.75.152:9000'
              
              
                }
              
              
                )
              
              
                # 2、使用上面創建的handler構建一個opener
              
              
	opener 
              
                =
              
               request
              
                .
              
              build_opener
              
                (
              
              handler
              
                )
              
              
                # 3、使用opener去發送一個請求
              
              
	resp 
              
                =
              
               opener
              
                .
              
              
                open
              
              
                (
              
              url
              
                )
              
              
                print
              
              
                (
              
              resp
              
                .
              
              read
              
                (
              
              
                )
              
              
                )
              
            
          

這里需要了解到的就是在使用urlopen的時候,其實也是完成構建一個handler之后再創建了一個opener,最后發起的請求,這個過程只是在openurl中間隱藏了

常用的代理有:
西刺免費代理IP:https://www.xicidaili.com/nt/
快代理:https://www.kuaidaili.com/
代理云:http://www.dailiyun.com/

在需要測試發送請求的機器對應的外網地址,可以使用http://httpbin.org/ip方式獲取

小結

1、代理的原理:在請求目的服務器之前,先請求代理服務器,然后讓代理服務器去請求目的網站,代理服務器拿到目的網站的數據后,再轉發給我們的代碼
2、http://httpbin.org:這個網站可以方便的查看http請求的一些請求
3、在代碼中使用代理:
3.1 使用 urllib.request.ProxyHandler
3.2 傳入一個代理,這個代理是一個字典,字典的key是http或者https,value是ip:port
3.2 使用上一步創建的handler,以及request.build_handler創建一個opener對象
3.3 使用上一步創建的opener,使用open函數,發起請求

什么是cookie

在網站中,http請求是無狀態的,也就是說即使第一次和服務器連接后并且登陸成功后,第二次請求服務器依然不能知道當前是哪個用戶。cookie的出現就是為了解決這個問題,第一次登陸后服務器返回一些數據(cookie)給瀏覽器,然后瀏覽器保存在本地,當該用戶發送第二次請求的時候,就會自動的把上傳請求存儲的cookie數據自動的攜帶給服務器,服務器通過瀏覽器攜帶的數據就能判斷當前用戶是哪個了。cookie存儲的數據量有限,不同的瀏覽器有不同的存儲大小,但一般不操過4KB,因此使用cookie只能存儲一些小量的數據

cookie的格式

            
              Set
              
                -
              
              Cookie
              
                ;
              
              NAME
              
                -
              
              VALUE
              
                ;
              
              Expires
              
                /
              
              Max
              
                -
              
              age
              
                -
              
              DATE
              
                ;
              
              Path
              
                -
              
              PATH
              
                ;
              
              Domain
              
                -
              
              DOMAIN_NAME
              
                ;
              
              SECURE

            
          

參數含義:
NAME:cookie的名字
VALUE:cookie的制
Expires:cookie的過期時間
Path:cookie作用的域名
Domain:cookie作用的域名
SECURE:是否只在https寫一下起作用

下面以訪問百度為例
python-爬蟲-網絡請求(二)_第2張圖片
可以看到,cookie都是放在Response Headers中間的

使用cookielib庫和HTTPCookieProcessor模擬登陸

Cookie是指網站服務器為了辨別用戶身份和進行Session跟蹤,而存儲在用戶用戶瀏覽器上的文本文件,Cookie可以保持登陸信息到用戶下次與服務器的會話
這里講點題外話:
要將byte類型轉為str類型,轉換過程是byte -> decode -> str
要將str類型轉為byte類型,轉換過程是str -> encode -> byte
示例:
python-爬蟲-網絡請求(二)_第3張圖片
以上的方式是通過瀏覽器首先登陸成功之后,在后面頁面訪問的時候,通過Request Header中間獲取到的Cookie,將這個Cookie放在請求頭中間,使用代碼進行訪問
其實這樣的方式還不是最好的,Cookie是服務端發出的,此時還是copy的瀏覽器的Cookie,更好的方式則是通過模擬登陸之后自動保存Cookie,最后攜帶這個Cookie發起后面的請求


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 库尔勒市| 乐亭县| 兴业县| 新绛县| 罗平县| 盐津县| 邓州市| 视频| 龙海市| 辽阳县| 榆林市| 兰西县| 库尔勒市| 堆龙德庆县| 碌曲县| 积石山| 柳林县| 沂南县| 江达县| 聂拉木县| 易门县| 二手房| 正阳县| 龙口市| 镇坪县| 稻城县| 高安市| 山阴县| 黄大仙区| 张掖市| 焦作市| 夹江县| 社会| 大兴区| 长白| 肥城市| 海门市| 台安县| 莫力| 城固县| 四平市|