urllib的用法

urllib 是 Python 內(nèi)置的 HTTP 請(qǐng)求庫(kù),它包含四個(gè)模塊:
1.發(fā)送請(qǐng)求
2.處理異常模塊
3.parse解析模塊的使用
4.Handler處理器 和 自定義Opener
5.robot協(xié)議介紹
1)發(fā)送請(qǐng)求之get方法
GET請(qǐng)求一般用于我們向服務(wù)器獲取數(shù)據(jù)
爬取網(wǎng)頁(yè):

導(dǎo)入模塊:
import urllib.request
import re
class NeiHan():
def __init__(self):
    #定位爬的url地址
    self.url = 'http://www.neihan8.com/wenzi//'
#請(qǐng)求頭
    self.headers = {
        'User-Agent': "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0"
    }
def loadpage(self, url):
    # 構(gòu)建request
    request = urllib.request.Request(url=self.url, headers=self.headers)
    # 發(fā)起請(qǐng)求
    response = urllib.request.urlopen(request)
    # 內(nèi)容編碼
    content = response.read().decode()
    #正則:
    pattern = re.compile(r'<div.*?class="desc">(.*?)</div>', re.S)
    #提取內(nèi)容
    neihan_list = pattern.findall(content)
    #內(nèi)容寫入
    for neihan in neihan_list:
        self.writepage(neihan)
#寫入到neihan.txt文件
def writepage(self, neihan):
    with open('neihan.txt', 'a') as f:
        f.write(neihan + '\n')
if __name__ == '__main__':
      c = NerHan()
      c.loadpage()

2)發(fā)送請(qǐng)求之post方法
Request請(qǐng)求對(duì)象的里有data參數(shù)殃姓,它就是用在POST里的望伦,我們要傳送的數(shù)據(jù)就是這個(gè)參數(shù)data,data是一個(gè)字典豁状,里面要匹配鍵值對(duì)。

import urllib.request
#工具
import urllib.parse
#請(qǐng)求頭
headers = {
    'User-Agent': 'Mozilla /     5.0(X11;Ubuntu;Linuxx86_64;rv: 54.0) Gecko /     20100101Firefox / 54.0'
}
#測(cè)試
url = 'https://httpbin.org/post'
#構(gòu)建post請(qǐng)求的表單數(shù)據(jù)
data = {
    'name': 'xiaohu',
    'age': 20
}
#將參數(shù)轉(zhuǎn)為url編碼格式,并轉(zhuǎn)為bytes類型的數(shù)據(jù)
params = urllib.parse.urlencode(data).encode()
#構(gòu)建request
request = urllib.request.Request(url=url, data=params,     headers=headers)
#發(fā)起請(qǐng)求獲取響應(yīng)結(jié)果
response = urllib.request.urlopen(request)
content = response.read().decode()
print(content)

GET方式是直接以鏈接形式訪問(wèn),鏈接中包含了所有的參數(shù)出革,服務(wù)器端用Request.QueryString獲取變量的值。如果包含了密碼的話是一種不安全的選擇覆履,不過(guò)你可以直觀地看到自己提交了什么內(nèi)容蹋盆。

POST則不會(huì)在網(wǎng)址上顯示所有的參數(shù)费薄,服務(wù)器端用Request.Form獲取提交的數(shù)據(jù)硝全,在Form提交的時(shí)候。但是HTML代碼里如果不指定 method 屬性楞抡,則默認(rèn)為GET請(qǐng)求伟众,F(xiàn)orm中提交的數(shù)據(jù)將會(huì)附加在url之后,以?分開與url分開召廷。

url.parse :定義了url的標(biāo)準(zhǔn)接口凳厢,實(shí)現(xiàn)url的各種抽取
parse模塊的使用:url的解析账胧,合并,編碼先紫,解碼

import urllib.parse

url = 'https://book.qidian.com/info/1004608738?wd=123&page=20#Catalog'

# 把URL拆開
print(urllib.parse.urlparse(url))
url_parmas = ('https', 'book.qidian.com', '/info/1004608738', '', 'wd=123&page=20', 'Catalog')
print(urllib.parse.urlunparse(url_parmas))
#將某一個(gè)不完整的鏈接拼接為一個(gè)完整鏈接
base_url = 'https://book.qidian.com/info/1004608738?wd=123&page=20#Catalog'
sub_url = '/info/100861102'
print(urllib.parse.urljoin(base_url,sub_url))
#將字典形式的參數(shù)序列化為url編碼后的字符串
#urllib.parse.urlencode()
parmas_str = 'page=20&wd=123'
parmas = urllib.parse.parse_qs(parmas_str)
print(parmas)

#將中文轉(zhuǎn)換為URL編碼格式
word = '中國(guó)夢(mèng)'
url = 'http://www.baidu.com/s?wd='+urllib.parse.quote(word)
print(urllib.parse.quote(word))
print(url)

#將URL編碼進(jìn)行解碼
url = 'http://www.baidu.com/s?wd=%E4%B8%AD%E5%9B%BD%E6%A2%A6'
print(urllib.parse.unquote(url))

urllib 的異常錯(cuò)誤處理

我們?cè)诎l(fā)送請(qǐng)求的過(guò)程中治泥,如果網(wǎng)絡(luò)環(huán)境不好,或者出現(xiàn)了其他問(wèn)題遮精,會(huì)出現(xiàn)請(qǐng)求異常居夹,如果不處理這些異常,程序很可能會(huì)崩潰本冲,所以我們需要處理請(qǐng)求異常問(wèn)題.

這里主要說(shuō)的是URLError和HTTPError准脂,以及對(duì)它們的錯(cuò)誤處理。

URLError:來(lái)自u(píng)rllib庫(kù)的error模塊檬洞,繼承自O(shè)SError,由request模塊產(chǎn)生的異常都可以通過(guò)捕捉這個(gè)類來(lái)處理.

產(chǎn)生的原因主要有:

  1. 沒(méi)有網(wǎng)絡(luò)連接
    2.服務(wù)器連接失敗
  2. 找不到指定的服務(wù)器

它具有一個(gè)屬性reason,返回錯(cuò)誤的原因

import urllib.error
import urllib.request


try:
    urllib.request.urlopen('http://www.baidu.com',timeout=0.01)
except urllib.error.URLError as e:
       print(e.reason)


try:
    urllib.request.urlopen('https://www.qidian.com/all/nsacnscn.htm')
except urllib.error.HTTPError as e:
    print(e.reason)
    print(e.code)
    print(e.headers)


try:
   urllib.request.urlopen('https://www.qidian.com/all/nsacnscn.htm')
except Exception as e:
    print(e)

常見(jiàn)的HTTP狀態(tài)碼:

200 - 請(qǐng)求成功
301 - 資源(網(wǎng)頁(yè)等)被永久轉(zhuǎn)移到其它URL
302 - 資源(網(wǎng)頁(yè)等)被臨時(shí)轉(zhuǎn)移到其它URL
401 - 未授權(quán)
403 - 禁止訪問(wèn)
408 - 請(qǐng)求超時(shí)
404 - 請(qǐng)求的資源(網(wǎng)頁(yè)等)不存在
500 - 內(nèi)部服務(wù)器錯(cuò)誤
503 - 服務(wù)器不可用

基本的urlopen()方法不支持代理狸膏、cookie等其他的HTTP/HTTPS高級(jí)功能。所以要支持這些功能:
使用相關(guān)的 Handler處理器 來(lái)創(chuàng)建特定功能的處理器對(duì)象添怔;
然后通過(guò) urllib.request.build_opener()方法使用這些處理器對(duì)象湾戳,創(chuàng)建自定義opener對(duì)象;
使用自定義的opener對(duì)象广料,調(diào)用open()方法發(fā)送請(qǐng)求院塞。

import urllib.request

url = "http://www.baidu.com"

# 處理http請(qǐng)求 ctrl+shift+u 大寫變小寫
httphandler = urllib.request.HTTPHandler(debuglevel=1)

# 處理https請(qǐng)求的handler
# httpshandler = urllib.request.HTTPsHandler()

# 第二步 創(chuàng)建一個(gè)opener
opener = urllib.request.build_opener(httphandler)

# 創(chuàng)建一個(gè)請(qǐng)求
request = urllib.request.Request(url=url)

# 發(fā)送請(qǐng)求
# urllib.request.urlopen(request)這是原來(lái)的發(fā)送請(qǐng)求方法
response = opener.open(request)

# 讀取數(shù)據(jù)

content = response.read().decode()

with open('baidu.html', 'w') as f:
f.write(content)

代理:

基本原理: 代理實(shí)際上指的就是代理服務(wù)器,英文叫作proxy server性昭,它的功能是代理網(wǎng)絡(luò)用戶去取得網(wǎng)絡(luò)信息拦止。形象地說(shuō),它是網(wǎng)絡(luò)信息的中轉(zhuǎn)站糜颠。在我們正常請(qǐng)求一個(gè)網(wǎng)站時(shí)汹族,其實(shí)是發(fā)送了請(qǐng)求給Web服務(wù)器,Web服務(wù)器把響應(yīng)傳回給我們其兴。如果設(shè)置了代理服務(wù)器顶瞒,實(shí)際上就是在本機(jī)和服務(wù)器之間搭建了一個(gè)橋,此時(shí)本機(jī)不是直接向Web服務(wù)器發(fā)起請(qǐng)求元旬,而是向代理服務(wù)器發(fā)出請(qǐng)求榴徐,請(qǐng)求會(huì)發(fā)送給代理服務(wù)器,然后由代理服務(wù)器再發(fā)送給Web服務(wù)器匀归,接著由代理服務(wù)器再把Web服務(wù)器返回的響應(yīng)轉(zhuǎn)發(fā)給本機(jī)坑资。這樣我們同樣可以正常訪問(wèn)網(wǎng)頁(yè),但這個(gè)過(guò)程中Web服務(wù)器識(shí)別出的真實(shí)IP就不再是我們本機(jī)的IP了穆端,就成功實(shí)現(xiàn)了IP偽裝袱贮,這就是代理的基本原理
代理的作用:
1.突破自身IP訪問(wèn)限制
2.訪問(wèn)一些單位或團(tuán)體內(nèi)部資源
3.提高訪問(wèn)速度
4.隱藏真實(shí)IP
1.根據(jù)協(xié)議劃分:
FTP代理服務(wù)器
HTTP代理服務(wù)器
SSL/TLS代理
SOCKS代理
根據(jù)匿名內(nèi)容劃分:
高度匿名代理
普通匿名代理
透明代理

import urllib.request
import urllib.parse

# 免費(fèi)代理
# proxy = {
#     'http': '61.176.223.7:58822',
#     'https': '218.76.253.201:61408',
# }

# 構(gòu)建一個(gè)私密代理Handler,需要加上私密代理賬戶的用戶名和密碼
authproxy = {
    "https": "496155678:tx4p1gbw@112.74.108.33:16817",
    # "http": "496155678:tx4p1gbw@112.74.108.33:16817"
}

# 創(chuàng)建處理代理的handler
proxyhandler = urllib.request.ProxyHandler(
    proxies = authproxy
)

# 創(chuàng)建一個(gè)opener

opener = urllib.request.build_opener(proxyhandler)

# 構(gòu)造一個(gè)請(qǐng)求

# request = urllib.request.Request(url='http://www.baidu.com')

# 發(fā)送請(qǐng)求

# response = opener.open(request)


url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
    'Referer': 'https://www.lagou.com/jobs/list_java?labelWords=&fromSearch=true&suginput=?labelWords=hot',
    'X-Requested-With': 'XMLHttpRequest',
    'Origin': 'https://www.lagou.com',
'Cookie': '_ga=GA1.2.454842362.1523882199; user_trace_token=20180416203639-cf8fa21d-4172-11e8-87b1-525400f775ce; LGUID=20180416203639-cf8fa4c6-4172-11e8-87b1-525400f775ce; _gid=GA1.2.357008350.1545287354; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22166af40632b7e4-0d1fb84d73b02a-346e780b-1024000-166af40632c733%22%2C%22%24device_id%22%3A%22166af40632b7e4-0d1fb84d73b02a-346e780b-1024000-166af40632c733%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_referrer_host%22%3A%22%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%7D%7D; showExpriedIndex=1; showExpriedCompanyHome=1; showExpriedMyPublish=1; hasDeliver=66; index_location_city=%E5%85%A8%E5%9B%BD; JSESSIONID=ABAAABAAAFCAAEG69A81B4AAC041DE1DF146C1C4175134C; _gat=1; LGSID=20181221104450-63482a8c-04ca-11e9-9f54-5254005c3644; PRE_UTM=; PRE_HOST=www.baidu.com; PRE_SITE=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3D_T_xi2Zd5W1_6G3zKFKezYvVu0lSBC5FQIr4HeQYOEa%26wd%3D%26eqid%3Dbdffabc60000f773000000025c1c5397; PRE_LAND=https%3A%2F%2Fwww.lagou.com%2F; Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1545303897,1545303905,1545352391,1545360291; LG_LOGIN_USER_ID=2d426d30feeb0777f3fc1657c0ea320fe465c87ef5bbbe5e; _putrc=42E0B5E87AD73B68; login=true; unick=%E8%B5%B5%E5%BA%86%E5%85%83; SEARCH_ID=94e60c5736f746ca915c2fad34993630; LGRID=20181221105414-b345f6f4-04cb-11e9-87ca-525400f775ce; Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1545360856; TG-TRACK-CODE=index_hotsearch; gate_login_token=275f6c1c24a8e56f015e157826f0c802878a39df65bfedc1',
}

data = {
    'first': 'false',
    'pn': 2,
    'kd': 'java'
}

# 傳遞的數(shù)據(jù)要進(jìn)行二進(jìn)制編碼
params = urllib.parse.urlencode(data).encode()

request = urllib.request.Request(url=url, headers=headers, data=params)

#把自定義的opener當(dāng)初全局使用
# urllib.request.install_opener(opener)
# response = urllib.request.urlopen(request)

response = opener.open(request)

print(response.read().decode())

# 打印內(nèi)容

# with open("proxybaidu.html", 'w') as f:
#     f.write(response.read().decode())

# print(response.read().decode())

Cookie

Cookie 是指某些網(wǎng)站服務(wù)器為了辨別用戶身份和進(jìn)行Session跟蹤体啰,而儲(chǔ)存在用戶瀏覽器上的文本文件攒巍,Cookie可以保持登錄信息到用戶下次與服務(wù)器的會(huì)話嗽仪。

Cookie原理 HTTP是無(wú)狀態(tài)的面向連接的協(xié)議, 為了保持連接狀態(tài), 引入了Cookie機(jī)制 Cookie是http消息頭中的一種屬性

from http import cookiejar
import urllib.request
import urllib.parse

# 先創(chuàng)建一個(gè)cookiejar對(duì)象,用來(lái)保存cookie
cookiejar = cookiejar.CookieJar()

# 創(chuàng)建一個(gè)能處理cookie的handler
cookie_handler = urllib.request.HTTPCookieProcessor(cookiejar)

# 生成一個(gè)opener對(duì)象
opener = urllib.request.build_opener(cookie_handler)

# 老登錄接口
url = 'http://www.renren.com/PLogin.do'

# 參數(shù)
data = {
'email': "496155678@qq.com",
'password': '123456789'
}

# 轉(zhuǎn)成二進(jìn)制數(shù)據(jù) 進(jìn)行傳輸
params = urllib.parse.urlencode(data).encode()

#構(gòu)建request
request = urllib.request.Request(url=url,data=params)

#發(fā)起請(qǐng)求
opener.open(request)
'''

只要登錄成功柒莉,自定義的opener就會(huì)把登錄后的cookie存到cookiejar當(dāng)中

如果繼續(xù)發(fā)起請(qǐng)求闻坚,就會(huì)把cookie自動(dòng)帶上
'''
#繼續(xù)發(fā)起請(qǐng)求
request1 = urllib.request.Request(url='http://www.renren.com/966325509/profile')

reponse = opener.open(request1)

with open('cookjarrenren.html','w')as f:
   f.write(reponse.read().decode())
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市兢孝,隨后出現(xiàn)的幾起案子鲤氢,更是在濱河造成了極大的恐慌,老刑警劉巖西潘,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卷玉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡喷市,警方通過(guò)查閱死者的電腦和手機(jī)相种,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)品姓,“玉大人寝并,你說(shuō)我怎么就攤上這事「贡福” “怎么了衬潦?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)植酥。 經(jīng)常有香客問(wèn)我镀岛,道長(zhǎng),這世上最難降的妖魔是什么友驮? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任漂羊,我火速辦了婚禮,結(jié)果婚禮上卸留,老公的妹妹穿的比我還像新娘走越。我一直安慰自己,他們只是感情好耻瑟,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布旨指。 她就那樣靜靜地躺著,像睡著了一般喳整。 火紅的嫁衣襯著肌膚如雪谆构。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天算柳,我揣著相機(jī)與錄音低淡,去河邊找鬼。 笑死瞬项,一個(gè)胖子當(dāng)著我的面吹牛蔗蹋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播囱淋,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼猪杭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了妥衣?” 一聲冷哼從身側(cè)響起皂吮,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎税手,沒(méi)想到半個(gè)月后蜂筹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芦倒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年艺挪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兵扬。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡麻裳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出器钟,到底是詐尸還是另有隱情津坑,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布傲霸,位于F島的核電站疆瑰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏昙啄。R本人自食惡果不足惜乃摹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望跟衅。 院中可真熱鬧孵睬,春花似錦、人聲如沸伶跷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)叭莫。三九已至蹈集,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雇初,已是汗流浹背拢肆。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人郭怪。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓支示,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親鄙才。 傳聞我的和親對(duì)象是個(gè)殘疾皇子颂鸿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • 什么是Urllib: Urllib是python內(nèi)置的HTTP請(qǐng)求庫(kù) 包括以下模塊 urllib.request ...
    啊煙雨閱讀 1,295評(píng)論 0 5
  • Urllib庫(kù)是Python中的一個(gè)功能強(qiáng)大、用于操作URL攒庵,并在做爬蟲的時(shí)候經(jīng)常要用到的庫(kù)嘴纺。在Python2.x...
    吳某人_0ad9閱讀 369評(píng)論 0 0
  • urllib的用法 什么是Urllib? Handler處理器 和 自定義Opener 簡(jiǎn)單的自定義opener(...
    風(fēng)雨聲豪入夢(mèng)中閱讀 490評(píng)論 0 0
  • Urllib庫(kù)是Python中的一個(gè)功能強(qiáng)大浓冒、用于操作URL栽渴,并在做爬蟲的時(shí)候經(jīng)常要用到的庫(kù)。在我們爬取一個(gè)網(wǎng)頁(yè)的...
    爽爽ing閱讀 357評(píng)論 0 0
  • urllib是Python自帶的標(biāo)準(zhǔn)庫(kù)稳懒,無(wú)需安裝闲擦,直接可以用。 提供了如下功能: 網(wǎng)頁(yè)請(qǐng)求 響應(yīng)獲取 代理和coo...
    時(shí)光清淺_許你心安_閱讀 34,709評(píng)論 0 3