urllib2是Python中用來抓取網頁的庫,urllib2 是 Python2.7 自帶的模塊(不須要下載,導入便可使用)
在python2.x裏面有urllib和urllib2;在python3.x裏面就把urllib和urllib2合成一個urllib;urllib3是在python3.x了裏面新增的第三方擴展。
urllib2 官方文檔:https://docs.python.org/2/lib...
urllib2 源碼:https://hg.python.org/cpython...
urllib2 在 python3.x 中被改成urllib.requestjavascript
來先看一個簡單的Demo,經過請求訪問百度html
import urllib.request # 向指定的url地址發送請求,並返回服務器響應的類文件對象 response = urllib.request.urlopen("http://www.baidu.com/") # 服務器返回的類文件對象支持Python文件對象的操做方法 # read()方法就是讀取文件裏的所有內容,返回字符串 html = response.read() # 打印響應內容 print(html)
咱們已經拿到百度的首頁了,可是目前出現了第一個問題就是,當你使用urllib2去訪問的時候,它的User-Agent是Python-urllib/3.6 (user-agent決定用戶的瀏覽器)java
咱們須要稍微假裝下,要否則第一步就會被反爬蟲發現python
#!/usr/bin/env python # -*- coding:utf-8 -*- import urllib.request # urllib2 的User-Agent: Python-urllib/2.7 # User-Agent 爬蟲和反爬蟲的第一步 ua_headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36" } # 經過urllib.request.Request() 方法構造一個請求對象 request = urllib.request.Request("http://www.baidu.com/", headers = ua_headers) # 向指定的url地址發送請求,並返回服務器響應的類文件對象 # urllib.request.urlopen()參數便可以是字符串也能夠是對象 response = urllib.request.urlopen(request) # 服務器返回的類文件對象支持Python文件對象的操做方法 # read()方法就是讀取文件裏的所有內容,返回字符串 html = response.read() # 返回 HTTP的響應碼,成功返回200,4服務器頁面出錯,5服務器問題 print(response.getcode()) # 返回 返回實際數據的實際URL,防止重定向問題 print(response.geturl()) # 返回 服務器響應的HTTP報頭 print(response.info()) # 打印響應內容 #print(html)
在url後面直接拼接參數,這種請求方式爲get請求
#!/usr/bin/python #coding:utf-8 from urllib import request,parse def loadPage(fullUrl,filename): """ 做用:根據url發送請求,獲取服務器響應文件 url: 須要爬取的url地址 filename : 處理的文件名 """ print('正在下載' + filename) headers = {"User_Agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36"} # 構造請求對象 request1 = request.Request(fullUrl,headers = headers); return request.urlopen(request1).read() def wirtePage(html,filename): """ 做用:將html內容寫入到本地 html:服務器相應的文件內容 """ print('正在保存' + filename) #文件寫入 with open(filename,'w') as f: # 此時打印的html僞bytes格式的,f.write()參數須要字符串 f.write(html.decode(encoding='utf-8')) print ('-' * 30) def tiebaSpider(url,beginPage,endPage): for page in range(beginPage,endPage+1): pn = (page-1) * 50 filename = "第" + str(page) +'頁.html' fullUrl = url +'&pn='+str(pn) # 發起請求 html = loadPage(fullUrl,filename) print(html) # 寫網頁 wirtePage(html,filename) if __name__ == '__main__': kw = input('請輸入爬去的貼吧名:') beginPage = int(input('請輸入起始頁:')) endPage = int(input('請輸入結束頁')) url = 'http://tieba.baidu.com/f?' key = parse.urlencode({"kw":kw}) fullUrl = url + key tiebaSpider(fullUrl,beginPage,endPage)
有些網站的查詢傳參不是直接在URL上面拼接並且經過post form data進行,這個時候傳遞就要模擬post請求
from urllib import request,parse # 經過抓包的方式獲取的url,並非瀏覽器上顯示的url url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule" # 完整的headers headers = { "Accept" : "application/json, text/javascript, */*; q=0.01", "X-Requested-With" : "XMLHttpRequest", "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36", "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8", } # 用戶接口輸入 key = input("請輸入須要翻譯的文字:") # 發送到web服務器的表單數據 formdata = { "from" : "AUTO", "to" : "AUTO", "smartresult" : "dict", "client" : "fanyideskweb", "type" : "AUTO", "i" : key, "doctype" : "json", "keyfrom" : "fanyi.web", "ue" : "UTF-8", "version":"2.1", "action" : "FY_BY_CLICKBUTTON", "typoResult" : "false" } # 通過urlencode轉碼 data = parse.urlencode(formdata).encode('utf-8') print(data) # 若是Request()方法裏的data參數有值,那麼這個請求就是POST # 若是沒有,就是Get request1 = request.Request(url, data = data, headers = headers) print(request.urlopen(request1).read().decode('utf-8'))
有些時候頁面上面是空的,內容經過ajax來加載,那麼咱們爬蟲須要關注點就應該到數據源這個位置,ajax加載的頁面,數據源必定是json,拿到json也就拿到了數據
![]()
from urllib import request, parse url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action" headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"} formdata = { "start":"0", "limit":"20" } data = parse.urlencode(formdata).encode('utf-8') request1 = request.Request(url, data = data, headers = headers) print(request.urlopen(request1).read().decode('utf-8'))