By 平常學python html
如下爲我的在學習過程當中作的筆記總結之爬蟲經常使用庫urllibpython
urlib庫爲python3的HTTP內置請求庫git
urilib的四個模塊:github
urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,cadefault=False,context=None)瀏覽器
示例代碼:markdown
1from urllib import request 2 3# 請求獲取網頁返回內容 4response = request.urlopen('https://movie.douban.com/') 5# 獲取網頁返回內容 6print(response.read().decode('utf-8')) 7# 獲取狀態碼 8print(response.status) 9# 獲取請求頭 10print(response.getheaders())
1# 對請求頭進行遍歷 2for k, v in response.getheaders(): 3 print(k, '=', v)
可使用上面的代碼對一些網站進行請求了,可是當須要一些反爬網站時,這就不行了,這時咱們須要適當地增長請求頭進行請求,這時就須要使用複雜一點的代碼了,這時咱們須要用到Request對象cookie
代碼示例:python爬蟲
1# 請求頭 2headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'} 3requests = request.Request('https://movie.douban.com/', headers=headers) # 加入本身的請求頭更加接近瀏覽器 4# 進行請求,把Request對象傳入urlopen參數中 5response = request.urlopen(requests) 6print(response.read().decode('utf-8'))
這個我添加了請求頭進行請求,使我發送的請求更加接近瀏覽器的行爲。能夠對應一些反爬網站了ide
若是網站須要進行登錄,這時須要用到post方法,用上面的也是能夠的。代碼以下:post
1from urllib import request, parse 2# 使用post方法來進行模擬登錄豆瓣 3data = {'source': 'None', 4 'redir': 'https://www.douban.com/', 5 'form_email': 'user', 6 'form_password': 'passwd', 7 'remember': 'on', 8 'login': '登陸'} 9# 將data的字典類型轉換爲get請求方式 10data = bytes(parse.urlencode(data), encoding='utf-8') 11requests = request.Request('https://accounts.douban.com/login', headers=headers, data=data, method='POST') 12response = request.urlopen(requests) 13print(response.read().decode('utf-8'))
這裏我用到了data的參數把登錄須要的參數傳進去,還加了個請求方法Method
parse.urlencode()後面有講
這裏還有另一種添加請求頭的方法
Request.add_header(): 參數有兩個,分別爲請求頭對應的鍵和值,這種方法一次只能添加一個請****求頭,添加多個須要用到循環或者直接用前面的方法添加多個請求頭
在登錄了網站以後,咱們須要用到cookie來保存登錄信息,這時就須要獲取cookie了。urllib獲取cookie比較麻煩。
代碼示例以下:
1from http import cookiejar 2# 獲取cookie 3cookie = cookiejar.CookieJar() 4# 獲取助手把cookie傳進去 5handler = request.HTTPCookieProcessor(cookie) 6# 獲取opener進行請求網站 7opener = request.build_opener(handler) 8# 請求網頁 9response = opener.open('https://movie.douban.com/') 10# 打印cookie 11for c in cookie: 12 print(c.name, '=', c.value)
單純地打印沒什麼用,咱們須要把他存入文件來保存,下次使用時再次加載cookie來登錄
保存cookie爲文件:
1from http import cookiejar 2# 將cookie保存在文件中 3filename = 'cookie.txt' 4cookie = cookiejar.MozillaCookieJar(filename) # 表示使用Mozilla的cookie方式存儲和讀取 5handler = request.HTTPCookieProcessor(cookie) 6opener = request.build_opener(handler) 7opener.open('https://movie.douban.com/') 8# 保存文件 9cookie.save(ignore_discard=True, ignore_expires=True)
另外一種保存方法:
1from http import cookiejar 2cookie = cookiejar.LWPCookieJar(filename) # 表示 Set-Cookie3 文件格式存儲和讀取 3handler = request.HTTPCookieProcessor(cookie) 4opener = request.build_opener(handler) 5opener.open('https://movie.douban.com/') 6# 保存文件 7cookie.save(ignore_discard=True, ignore_expires=True)
這兩種保存格式都是不同的,須要保存的內容同樣。
保存能夠了,這時就須要用到加載了,固然也能夠。代碼以下:
1from http import cookiejar 2# 從cookie文件加載到網頁上實現記住登錄 3cookie = cookiejar.LWPCookieJar() 4# 加載文件 5cookie.load(filename, ignore_discard=True, ignore_expires=True) 6handler = request.HTTPCookieProcessor(cookie) 7opener = request.build_opener(handler) 8opener.open('https://movie.douban.com/')
這樣就能夠實現不用密碼進行登錄了。
cookie小總結:在操做cookie時,都是分五步,以下:
若是有時你在同一ip連續屢次發送請求,會有被封ip的可能,這時咱們還須要用到代理ip進行爬取,代碼以下:
1proxy = request.ProxyHandler({ 2 'https': 'https://106.60.34.111:80' 3}) 4opener = request.build_opener(proxy) 5opener.open('https://movie.douban.com/', timeout=1)
能夠看到越複雜的請求都須要用到request.build_opener(),這個方法有點重要,請記住哈
將上面的使用代理ip的請求進行異常處理,以下:
1from urllib import request, error 2try: 3 proxy = request.ProxyHandler({ 4 'https': 'https://106.60.34.111:80' 5 }) 6 opener = request.build_opener(proxy) 7 opener.open('https://movie.douban.com/', timeout=1) 8except error.HTTPError as e: 9 print(e.reason(), e.code(), e.headers()) 10except error.URLError as e: 11 print(e.reason)
由於有時這個ip或許也被封了,有可能會拋出異常,因此咱們爲了讓程序運行下去進而進行捕捉程序
解析url:urllib.parse.urlparse(url, scheme='', allow_fragments=True)
簡單的使用:
1from urllib import request, parse 2# 解析url 3print(parse.urlparse('https://movie.douban.com/')) 4print(parse.urlparse('https://movie.douban.com/', scheme='http')) 5print(parse.urlparse('movie.douban.com/', scheme='http')) 6# 下面是結果 7ParseResult(scheme='https', netloc='movie.douban.com', path='/', params='', query='', fragment='') 8ParseResult(scheme='https', netloc='movie.douban.com', path='/', params='', query='', fragment='') 9ParseResult(scheme='http', netloc='', path='movie.douban.com/', params='', query='', fragment='')
能夠看出加了scheme參數和沒加的返回結果是有區別的。而當scheme協議加了,而前面的url也包含協議,通常會忽略後面的scheme參數
既而後解析url,那固然也有反解析url,就是把元素串連成一個url
1from urllib import parse 2# 將列表元素拼接成url 3url = ['http', 'www', 'baidu', 'com', 'dfdf', 'eddffa'] # 這裏至少須要6個元素(我亂寫的,請忽視) 4print(parse.urlunparse(url)) 5# 下面是結果 6http://www/baidu;com?dfdf#eddffa
urlparse()接收一個列表的參數,並且列表的長度是有要求的,是必須六個參數以上,要不會拋出異常
1Traceback (most recent call last): 2 File "E:/anaconda/python_project/python3_spider/urllib_test.py", line 107, in <module> 3 print(parse.urlunparse(url)) 4 File "E:\anaconda\lib\urllib\parse.py", line 454, in urlunparse 5 _coerce_args(*components)) 6ValueError: not enough values to unpack (expected 7, got 6)
urllib.parse.urljoin():這個是將第二個參數的url缺乏的部分用第一個參數的url補齊
1# 鏈接兩個參數的url, 將第二個參數中缺的部分用第一個參數的補齊 2print(parse.urljoin('https://movie.douban.com/', 'index')) 3print(parse.urljoin('https://movie.douban.com/', 'https://accounts.douban.com/login')) 4# 下面是結果 5https://movie.douban.com/index 6https://accounts.douban.com/login
urllib.parse.urlencode():這個方法是將字典類型的參數轉爲請求爲get方式的字符串
1data = {'name': 'sergiojuue', 'sex': 'boy'} 2data = parse.urlencode(data) 3print('https://accounts.douban.com/login'+data) 4# 下面是結果 5https://accounts.douban.com/loginname=sergiojuue&sex=boy
還有個urllib.robotparse庫少用,就不說了,留給之後須要再去查文檔吧。
上面的只是我在學習過程當中的總結,若是有什麼錯誤的話,歡迎在留言區指出,還有就是須要查看更多用法的請查看文檔https://docs.python.org/3/library/urllib.html
須要代碼的能夠去個人github上面fork,給個star也行!
github:https://github.com/SergioJune/gongzhonghao_code/blob/master/python3_spider/urllib_test.py
學習過程當中看的大可能是崔慶才大佬的視頻:https://edu.hellobi.com/course/157