Urllib庫是python中的一個功能強大的,用於操做URL,並在做爬蟲的時候經常要用到的庫,在python2中,分為Urllib和Urllib2兩個庫,在python3之后就將兩個庫合並到Urllib庫中,使用方法有所不同,我使用的是python3。
第一步,先導入Urllib庫對應的模塊,import urllib.request 或者直接導入request模塊 from urllib import request
from urllib import request file = request.urlopen("http://www.baidu.com") #urlopen打開並爬取一個頁面,並將值賦給file,以百度為例 data = file.read() #read()讀取全部能容 dataline = file.readline() #readline()只讀取一行 # 分別打印兩個值 print(dataline) print(data)
打印結果:
這樣就將獲取的網頁的HTML代碼爬取下來了
爬取到數據之后我們怎么將爬取的網頁以網頁的形式進行保存
from urllib import request file = request.urlopen("http://www.baidu.com") data = file.read() fhandle = open("F:/爬蟲/1.html","wb") #通過open()函數打開該文件,“wb”以二進制寫入形式打開,不會的話可以學習一下之前的python的文件寫入操作。 #文件目錄自己先創建 fhandle.write(data) #將data數據寫入到 fhandle.close() #將文件關閉
然后找到該文件,用瀏覽器打開
圖片信息還未爬取,但至此我們已經網頁爬取並保存。
還有一種直接使用request模塊中的urlretrieve函數直接寫入
格式:urlretrieve(url,filename=本地地址)
from urllib import request filename=request.urlretrieve("http://www.qq.com",filename="F:/爬蟲/2.html" )
然后查看保存的路徑下的文件,打開之后
使用urlretrieve執行的過程中會產生一些緩存,可以使用函數urlcleanup()進行清除
還有寫其他的常用的方法如下:
返回與當前環境有關的信息 info()
獲取當前爬取網頁的狀態碼 getcode()
獲取當前爬取網頁的URL地址 geturl()
由於URL標准中之允許一部分的ASCII字符,比如數字,字母,部分表單符號等,其他不符合標准的要進行編碼,使用quote()
編碼之后進行解碼 unquote()
當然不是所有的網站都可以這么輕松的獲取到,很多網站都進行了反爬蟲設置,用瀏覽器可以打開但用爬蟲爬不到,此時我們就需要設置一些headers信息,模擬成瀏覽器去訪問這些網站。
首先打開瀏覽器,輸入www.baidu.com 然后按F12 在刷新一下網頁
點擊網絡就可以看到上面的圖了,然后點擊第一個和右邊的按鈕
你就可以看到這樣的
右邊的標頭就是headers,然后找到User-Agent,這個就是我們要用到的模擬瀏覽器的信息,將其復制下來
我們可以得到該信息 “User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36”
這樣我們就可以修改報頭,其中request()下的build_opener()和request.Request()下的add_header()都可以進行操作,如下:
from urllib import request url = "www.baidu.com" #僅僅是個例子 headers = ("User-Agent","User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36") opener = request.build_opener() opener.addheaders=[headers] data = opener.open(url).read() print(data)
還有一種方法是通過request.Request(url)方式進行操作如下:
from urllib import request urll = "http://www.baidu.com" req = request.Request(urll) req.add_header("User-Agent","User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36") #這里的鍵值對不止這一個,你也可以把所有的都寫上,比如Cookie、host都可以 data = request.urlopen(req).read() fhandle = open("F:/爬蟲/1.html","wb") fhandle.write(data) fhandle.close()
HTTP請求之GET請求
當我們用百度進行搜索時會看到網絡請求用的時get請求
可以看出搜索詞的關鍵字時wd,這樣我們可以通過構造類似的網址進行網絡請求,然后再將請求的網址保存
from urllib import request keywd = "中國是一個偉大的國家" key_code = request.quote(keywd) #漢字要編碼, urll = "http://www.baidu.com/s?wd="+key_code #拼接字符串 req = request.Request(urll) data = request.urlopen(req).read() fhandle = open("F:/爬蟲/3.html","wb") fhandle.write(data) fhandle.close()
然后打開本地保存的文件
從上面的示例中可以總結出,使用GET請求的思路如下:
1.構造對應的URL地址,該URL地址包含GET請求的字段名和字段內容的信息,並且URL滿足GET請求的格式,即 “http://網址?字段1=字段內容1&字段2=字段內容2”。
2.以頂印度額URL為參數,構建Request對象。
3.通過urlopen()打開構建的Request對象。
4.按需求進行后續處理的操作,比如讀取網頁的內容、將內容寫入文件等。
HTTP請求之POST請求
在注冊和登陸網站是我們基本上都會遇到post請求,下面舉個例子,這個是自己搭建的post請求網頁,很粗糙的一個,只是將post請求的用戶名個密碼提交之后打印在了頁面上。源碼如下:
<form action="<?=$_SERVER['PHP_SELF'] ?>" method="POST"> 用戶名<input type="text" name="username"><br> 密碼<input type="password" name="passwd"><br> <input type="submit" name="submit" value="提交"> </form> <?php if (isset($_POST['submit'])) { echo "<br>"; echo '用戶名:'.$_POST['username']."<br>"; echo "密碼:".$_POST['passwd'].'<br>'; } ?>
原始的頁面是
填寫用戶名和密碼之后的頁面
怎么構建post請求,一般的思路如下:
1.設置好URL網址
2.構建表單數據,並使用urllib.parse.urlencode對數據進行編碼處理
3.創建Request對象,參數包括URL地址和要傳遞的編碼處理
4.使用add_header()添加頭部信息,模擬瀏覽器進行爬取
5.使用urllib.request.urlopen()打開對應的Request對象,完成信息的傳遞
6.讀取或者寫入等操作
現在我們去爬一下上面的網站:http://192.168.199.247/mytest/index.php
至於構建表單數據,我們需要看一下源碼,打開網頁,按F12,找到from表單的部分。
從上面我們可以看出需要提交表單的兩個字段分別是:username、passwd。這樣我們就可以構造數據,POST請求時的數據構造都要是以字典的形式進行所以我們構造的函數為:
{"username":"root","passwd":"root"},我們將用戶名和密碼都設置為root,這只完之后我們進行編碼。然后創建Request對象之后就按着思路往下走就可以了
代碼:
from urllib import request from urllib import parse #編碼時需要用到的庫 url = "http://192.168.199.247/mytest/index.php" postdata = parse.urlencode({ "username":"root", "passwd":"root" }).encode("utf-8") #設置編碼格式為utf-8 req = request.Request(url,postdata) #在Request之后可以直接設置傳遞的數據 Request(url地址,傳遞的數據) req.add_header("User-Agent","User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36") data = request.urlopen(req).read() fhandle = open("F:/爬蟲/1.html","wb") fhandle.write(data) fhandle.close()