1. 程式人生 > >05_urllib(1)之傳送請求

05_urllib(1)之傳送請求

使用urllib的request模組,我們可以方便地實現請求的傳送並得到響應,本節就來看下它的具體用法。

1. urlopen()

urllib.request模組提供了最基本的構造HTTP請求的方法,利用它可以模擬瀏覽器的一個請求發起過程,同時它還帶有處理授權驗證(authenticaton)、重定向(redirection)、瀏覽器Cookies以及其他內容。

下面我們來看一下它的強大之處。這裡以Python官網為例,我們來把這個網頁抓下來:

1 2 3 4 import urllib.request   response = urllib.request.urlopen('https://www.python.org') print(response.read().decode('utf-8'))

執行結果如圖3-1所示。

圖3-1 執行結果

這裡我們只用了兩行程式碼,便完成了Python官網的抓取,輸出了網頁的原始碼。得到原始碼之後呢?我們想要的連結、圖片地址、文字資訊不就都可以提取出來了嗎?

接下來,看看它返回的到底是什麼。利用type()方法輸出響應的型別:

1 2 3 4 import urllib.request   response = urllib.request.urlopen('https://www.python.org')
print(type(response))
 

輸出結果如下:

1 <class 'http.client.HTTPResponse'>

 

可以發現,它是一個HTTPResposne型別的物件。它主要包含read()readinto()getheader(name)getheaders()fileno()等方法,以及msgversionstatusreasondebuglevelclosed等屬性。

得到這個物件之後,我們把它賦值為response變數,然後就可以呼叫這些方法和屬性,得到返回結果的一系列資訊了。

例如,呼叫read()方法可以得到返回的網頁內容,呼叫status屬性可以得到返回結果的狀態碼,如200代表請求成功,404代表網頁未找到等。

下面再通過一個例項來看看:

 
1 2 3 4 5 6 import urllib.request   response = urllib.request.urlopen('https://www.python.org') print(response.status) print(response.getheaders()) print(response.getheader('Server'))

 

執行結果如下:

1 2 3 200 [('Server', 'nginx'), ('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'SAMEORIGIN'), ('X-Clacks-Overhead', 'GNU Terry Pratchett'), ('Content-Length', '47397'), ('Accept-Ranges', 'bytes'), ('Date', 'Mon, 01 Aug 2016 09:57:31 GMT'), ('Via', '1.1 varnish'), ('Age', '2473'), ('Connection', 'close'), ('X-Served-By', 'cache-lcy1125-LCY'), ('X-Cache', 'HIT'), ('X-Cache-Hits', '23'), ('Vary', 'Cookie'), ('Strict-Transport-Security', 'max-age=63072000; includeSubDomains')] nginx

可見,前兩個輸出分別輸出了響應的狀態碼和響應的頭資訊,最後一個輸出通過呼叫getheader()方法並傳遞一個引數Server獲取了響應頭中的Server值,結果是nginx,意思是伺服器是用Nginx搭建的。

利用最基本的urlopen()方法,可以完成最基本的簡單網頁的GET請求抓取。

如果想給連結傳遞一些引數,該怎麼實現呢?首先看一下urlopen()函式的API:

1 urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

可以發現,除了第一個引數可以傳遞URL之外,我們還可以傳遞其他內容,比如data(附加資料)、timeout(超時時間)等。

下面我們詳細說明下這幾個引數的用法。

data引數

data引數是可選的。如果要新增該引數,並且如果它是位元組流編碼格式的內容,即bytes型別,則需要通過bytes()方法轉化。另外,如果傳遞了這個引數,則它的請求方式就不再是GET方式,而是POST方式。

下面用例項來看一下:

1 2 3 4 5 6 import urllib.parse import urllib.request   data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8') response = urllib.request.urlopen('http://httpbin.org/post', data=data) print(response.read())

這裡我們傳遞了一個引數word,值是hello。它需要被轉碼成bytes(位元組流)型別。其中轉位元組流採用了bytes()方法,該方法的第一個引數需要是str(字串)型別,需要用urllib.parse模組裡的urlencode()方法來將引數字典轉化為字串;第二個引數指定編碼格式,這裡指定為utf8

這裡請求的站點是httpbin.org,它可以提供HTTP請求測試。本次我們請求的URL為http://httpbin.org/post,這個連結可以用來測試POST請求,它可以輸出請求的一些資訊,其中包含我們傳遞的data引數。

執行結果如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 {      "args": {},      "data": "",      "files": {},      "form": {          "word": "hello"      },      "headers": {          "Accept-Encoding": "identity",          "Content-Length": "10",          "Content-Type": "application/x-www-form-urlencoded",          "Host": "httpbin.org",          "User-Agent": "Python-urllib/3.5"      },      "json": null,      "origin": "123.124.23.253",      "url": "http://httpbin.org/post" }

我們傳遞的引數出現在了form欄位中,這表明是模擬了表單提交的方式,以POST方式傳輸資料。

timeout引數

timeout引數用於設定超時時間,單位為秒,意思就是如果請求超出了設定的這個時間,還沒有得到響應,就會丟擲異常。如果不指定該引數,就會使用全域性預設時間。它支援HTTP、HTTPS、FTP請求。

下面用例項來看一下:

1 2 3 4 import urllib.request   response = urllib.request.urlopen('http://httpbin.org/get', timeout=1) print(response.read())

執行結果如下:

1 2 3 4 5 During handling of the above exception, another exception occurred:   Traceback (most recent call last): File "/var/py/python/urllibtest.py", line 4, in <module> response = urllib.request.urlopen('http://httpbin.org/get', timeout=1) ... urllib.error.URLError: <urlopen error timed out>

這裡我們設定超時時間是1秒。程式1秒過後,伺服器依然沒有響應,於是丟擲了URLError異常。該異常屬於urllib.error模組,錯誤原因是超時。

因此,可以通過設定這個超時時間來控制一個網頁如果長時間未響應,就跳過它的抓取。這可以利用try except語句來實現,相關程式碼如下:

1 2 3 4 5 6 7 8 9 import socket import urllib.request import urllib.error   try:     response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1) except urllib.error.URLError as e:     if isinstance(e.reason, socket.timeout):         print('TIME OUT')

這裡我們請求了http://httpbin.org/get測試連結,設定超時時間是0.1秒,然後捕獲了URLError異常,接著判斷異常是socket.timeout型別(意思就是超時異常),從而得出它確實是因為超時而報錯,列印輸出了TIME OUT

執行結果如下:

1 TIME OUT

按照常理來說,0.1秒內基本不可能得到伺服器響應,因此輸出了TIME OUT的提示。

通過設定timeout這個引數來實現超時處理,有時還是很有用的。

其他引數

除了data引數和timeout引數外,還有context引數,它必須是ssl.SSLContext型別,用來指定SSL設定。

此外,cafilecapath這兩個引數分別指定CA證書和它的路徑,這個在請求HTTPS連結時會有用。

cadefault引數現在已經棄用了,其預設值為False

前面講解了urlopen()方法的用法,通過這個最基本的方法,我們可以完成簡單的請求和網頁抓取。若需更加詳細的資訊,可以參見官方文件:https://docs.python.org/3/library/urllib.request.html

2. Request

我們知道利用urlopen()方法可以實現最基本請求的發起,但這幾個簡單的引數並不足以構建一個完整的請求。如果請求中需要加入Headers等資訊,就可以利用更強大的Request類來構建。

首先,我們用例項來感受一下Request的用法:

1 2 3 4 5 import urllib.request   request = urllib.request.Request('https://python.org') response = urllib.request.urlopen(request) print(response.read().decode('utf-8'))

可以發現,我們依然是用urlopen()方法來發送這個請求,只不過這次該方法的引數不再是URL,而是一個Request型別的物件。通過構造這個資料結構,一方面我們可以將請求獨立成一個物件,另一方面可更加豐富和靈活地配置引數。

下面我們看一下Request可以通過怎樣的引數來構造,它的構造方法如下:

1 class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)

 

  • 第一個引數url用於請求URL,這是必傳引數,其他都是可選引數。
  • 第二個引數data如果要傳,必須傳bytes(位元組流)型別的。如果它是字典,可以先用urllib.parse模組裡的urlencode()編碼。
  • 第三個引數headers是一個字典,它就是請求頭,我們可以在構造請求時通過headers引數直接構造,也可以通過呼叫請求例項的add_header()方法新增。

    新增請求頭最常用的用法就是通過修改User-Agent來偽裝瀏覽器,預設的User-Agent是Python-urllib,我們可以通過修改它來偽裝瀏覽器。比如要偽裝火狐瀏覽器,你可以把它設定為: 

     
    1 Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11
     
  • 第四個引數origin_req_host指的是請求方的host名稱或者IP地址。
  • 第五個引數unverifiable表示這個請求是否是無法驗證的,預設是False,意思就是說使用者沒有足夠許可權來選擇接收這個請求的結果。例如,我們請求一個HTML文件中的圖片,但是我們沒有自動抓取影象的許可權,這時unverifiable的值就是True`。
  • 第六個引數method是一個字串,用來指示請求使用的方法,比如GET、POST和PUT等。

下面我們傳入多個引數構建請求來看一下:

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from urllib import request, parse   url = 'http://httpbin.org/post' headers = {     'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',     'Host': 'httpbin.org' } dict = {     'name': 'Germey' } data = bytes(parse.urlencode(dict), encoding='utf8') req = request.Request(url=url, data=data, headers=headers, method='POST') response = request.urlopen(req) print(response.read().decode('utf-8'))

這裡我們通過4個引數構造了一個請求,其中url即請求URL,headers中指定了User-AgentHost,引數dataurlencode()bytes()方法轉成位元組流。另外,指定了請求方式為POST。

執行結果如下:

1 2 3 4 5

相關推薦

05_urllib1傳送請求

使用urllib的request模組,我們可以方便地實現請求的傳送並得到響應,本節就來看下它的具體用法。 1. urlopen() urllib.request模組提供了最基本的構造HTTP請求的方法,利用它可以模擬瀏覽器的一個請求發起過程,同時它還帶有處理授權驗證(authenticaton)

RecyclerView的使用1HelloWorld

prot pub lines isa osi -s pri 構造函數 java 原創文章。轉載請註明 http://blog.csdn.net/leejizhou/article/details/50670657 RecyclerView是伴隨Andr

20180813視頻筆記 深度學習基礎上篇1必備基礎知識點 深度學習基礎上篇2神經網絡模型視頻筆記:深度學習基礎上篇3神經網絡案例實戰 和 深度學習基礎下篇

計算 概念 人臉識別 大量 png 技巧 表現 lex github 深度學習基礎上篇(3)神經網絡案例實戰 https://www.bilibili.com/video/av27935126/?p=1 第一課:開發環境的配置 Anaconda的安裝 庫的安裝 Windo

SpringMVC學習系列1 初識SpringMVC

映射 lin logs intern fault lan 前端 png let /*springMvc的總結:(推薦,總共有十五章) *http://www.cnblogs.com/liukemng/p/3751338.html */ 1.什麽是Spring MVC:

ASP.NET MVC 實現頁落網資源分享網站+充值管理+後臺管理1資料庫設計

    本文主要講解本專案網站所應用到的知識點,及資料庫的相關設計: 一、知識點     (1)本專案主要採取ASP.NET MVC的程式設計模式,相信你已經瞭解到了MVC的具體含義是什麼,這裡不再贅述,有不瞭解的朋友,可以先

linux系統管理1 核心編譯選項檢視

三個方法 proc檔案系統 ubunut debain 紅帽等 proc檔案系統 /proc/config.gz This file shows you the compile-time configuration settings for the kernel (gzip compr

Vue-router1路由基礎

1. 使用 <component>標籤實現元件切換   <component> 是Vue提供的;有一個is屬性,is的作用就是顯示指定的元件      <template> <div> <h1>App根元件

Pytorch第一課:package-torch1張量初識

微博:https://weibo.com/wangxiaocaoai/profile?rightmod=1&wvr=6&mod=personinfo 微信公眾號:搜尋"AI躁動街" 本節要點: 1 張量 2 建立張量的方式 3 張量的索引,切片,連線

KgoUI1 技術選型angular 和 vue

    框架原始碼:碼雲          最近幾年前端技術發生了很大的變化,新技術,新開發模式層出不窮。之前div+css+js 包打天下的時代已經不復存在了。說到前端技術目前最火的莫過於三大mvvm框架

SpringMVC框架11.4 SpringMVC與 Struts區別

SpringMVC與 Struts區別 SpringMVC是通過方法的形參接收引數,可以以單例方式 使用,建議使用單例; Struts通過成員變數接收引數,在使用時 必須以多例方式 使用;   SpringMVC是 基於方法 開發(以方法為單位),一個請求的方法對應一個 H

SpringMVC框架11.3 自定義引數繫結

一、自定義引數繫結-屬性編輯器(不推薦) 問題:① 4.1 itemsList.jsp 中增加顯示 “訂購日期” 屬性;② JSP頁面中日期拿到的是字串,而提交到Controller中POJO類ItemsCustom 屬性物件的日期欄位要變成Date型別,即字串轉換成日期型別,無法自動轉

SpringMVC框架11.3 引數繫結

引數繫結 一、繫結簡單型別引數:整型、字串、float/double、日期、布林(eg:Controller中方法 public String editItemsSubmit(String name,Float price)) (eg:4.2 editItems.jsp 中 name

SpringMVC框架11.3 註解開發&Controller方法返回值

一、 註解開發基礎: 1. @RequestMapping 註解(在Controller類上或方法上,用於指定 url和請求方式): 1. 設定方法對應的URL(一個方法對應一個URL); 2. 設定請求的根路徑;(eg:http:// localhost:8080/project/bo

SpringMVC框架11.2 入門程式—SpringMVC與Mybatis整合

一、整合思路: 1. jar包: mybatis包、spring包、mybatis和spring整合包、資料庫驅動包、日誌包; 2. Spring管理: SpringMVC中編寫的 Handler(即Controller)、Mybatis的 SqlSessionFactory

SpringMVC框架11.2 入門程式—處理器對映器和處理器介面卡註解方式

1.DispatcherServlet載入時會預設載入 DispatcherServlet.properties 檔案,目的是為了載入裡面的處理器對映器、處理器介面卡、檢視解析器等各個元件;(所以 springmvc.xml 中 兩種處理器介面卡、兩種處理器介面卡、檢視解析器都可以省略;)

SpringMVC框架11.2 入門程式—常用的處理器對映器和處理器介面卡

1. 程式結構: 建立一個Web專案,匯入 Spring的 jar包: 使用 Spring3.2.0(帶SpringMVC模組) web.xml 檔案中配置 DispatcherServlet前端控制器 (DispatcherServlet作為 springmvc的中央排程

SpringMVC框架1總目錄

1. SpringMVC框架基礎: SpringMVC框架 MVC在 B/S系統中的應用 原理:前端控制器、處理器對映器、處理器介面卡、檢視解析器 入門程式 常用的處理器對映器和處理器介面卡 (網址: https://blog.csdn.net/qq_41029923/ar

Spring1 1.4_Spring WEBWeb 專案中使用 Spring

1. Spring負責物件的建立( 控制反轉 IOC),處理物件之間的依賴關係(依賴注入 DI) 2. Spring在 WEB應用中的使用:整合Mybatis、Hibernate、SpringMVC、Struts 3. 使用步驟: 引入 jar包: spring-core

MySQL1 基本知識

DBMS(資料庫管理系統) 分為兩類: – 基於共享檔案系統的DBMS ( Access ) – 基於客戶機——伺服器的DBMS ( MySQL、Oracle、SqlServer )   Windows平臺下下載:http://dev.mysql.com/downloads

Oracle1 匯入表

開啟PL/SQL  在左上角點選new按鈕 ,出現sql'編輯器 把已有的存放在一個比較方便的位置,我是在e盤下的oracle_biao資料夾下放了三個sql檔案; 例如:以此執行下面的三個命令 @e:/oracle_biao/hr_popul.sql @e:/oracl