国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

深入解析Python中的urllib2模塊

2020-01-04 17:57:36
字體:
供稿:網(wǎng)友

這篇文章主要介紹了Python中的urllib2模塊,包括一個利用其抓取網(wǎng)站生成RSS的小例子,需要的朋友可以參考下

Python 標(biāo)準(zhǔn)庫中有很多實用的工具類,但是在具體使用時,標(biāo)準(zhǔn)庫文檔上對使用細(xì)節(jié)描述的并不清楚,比如 urllib2 這個 HTTP 客戶端庫。這里總結(jié)了一些 urllib2 的使用細(xì)節(jié)。

Proxy 的設(shè)置

Timeout 設(shè)置

在 HTTP Request 中加入特定的 Header

Redirect

Cookie

使用 HTTP 的 PUT 和 DELETE 方法

得到 HTTP 的返回碼

Debug Log

Proxy 的設(shè)置

urllib2 默認(rèn)會使用環(huán)境變量 http_proxy 來設(shè)置 HTTP Proxy。如果想在程序中明確控制 Proxy 而不受環(huán)境變量的影響,可以使用下面的方式

 

 
  1. import urllib2 
  2. enable_proxy = True 
  3. proxy_handler = urllib2.ProxyHandler({"http" : 'http://some-proxy.com:8080'}) 
  4. null_proxy_handler = urllib2.ProxyHandler({}) 
  5.  
  6. if enable_proxy: 
  7. opener = urllib2.build_opener(proxy_handler) 
  8. else
  9. opener = urllib2.build_opener(null_proxy_handler) 
  10.  
  11. urllib2.install_opener(opener) 

這里要注意的一個細(xì)節(jié),使用 urllib2.install_opener() 會設(shè)置 urllib2 的全局 opener 。這樣后面的使用會很方便,但不能做更細(xì)粒度的控制,比如想在程序中使用兩個不同的 Proxy 設(shè)置等。比較好的做法是不使用 install_opener 去更改全局的設(shè)置,而只是直接調(diào)用 opener 的 open 方法代替全局的 urlopen 方法。

Timeout 設(shè)置

在老版 Python 中,urllib2 的 API 并沒有暴露 Timeout 的設(shè)置,要設(shè)置 Timeout 值,只能更改 Socket 的全局 Timeout 值。

 

 
  1. import urllib2 
  2.  
  3.  
  4. import socket 
  5. socket.setdefaulttimeout(10) # 10 秒鐘后超時 
  6. urllib2.socket.setdefaulttimeout(10) # 另一種方式 

在 Python 2.6 以后,超時可以通過 urllib2.urlopen() 的 timeout 參數(shù)直接設(shè)置。

 

 
  1. import urllib2 
  2. response = urllib2.urlopen('http://www.google.com', timeout=10) 

在 HTTP Request 中加入特定的 Header

要加入 header,需要使用 Request 對象:

 

 
  1. import urllib2 
  2. request = urllib2.Request(uri) 
  3. request.add_header('User-Agent''fake-client'
  4. response = urllib2.urlopen(request) 

對有些 header 要特別留意,服務(wù)器會針對這些 header 做檢查

User-Agent : 有些服務(wù)器或 Proxy 會通過該值來判斷是否是瀏覽器發(fā)出的請求

Content-Type : 在使用 REST 接口時,服務(wù)器會檢查該值,用來確定 HTTP Body 中的內(nèi)容該怎樣解析。常見的取值有:

application/xml : 在 XML RPC,如 RESTful/SOAP 調(diào)用時使用

application/json : 在 JSON RPC 調(diào)用時使用

application/x-www-form-urlencoded : 瀏覽器提交 Web 表單時使用

在使用服務(wù)器提供的 RESTful 或 SOAP 服務(wù)時, Content-Type 設(shè)置錯誤會導(dǎo)致服務(wù)器拒絕服務(wù)

Redirect

urllib2 默認(rèn)情況下會針對 HTTP 3XX 返回碼自動進行 redirect 動作,無需人工配置。要檢測是否發(fā)生了 redirect 動作,只要檢查一下 Response 的 URL 和 Request 的 URL 是否一致就可以了。

 

 
  1. import urllib2 
  2. response = urllib2.urlopen('http://www.google.cn'
  3. redirected = response.geturl() == 'http://www.google.cn' 

如果不想自動 redirect,除了使用更低層次的 httplib 庫之外,還可以自定義 HTTPRedirectHandler 類。

 

 
  1. import urllib2 
  2.  
  3. class RedirectHandler(urllib2.HTTPRedirectHandler): 
  4. def http_error_301(self, req, fp, code, msg, headers): 
  5. pass 
  6. def http_error_302(self, req, fp, code, msg, headers): 
  7. pass 
  8.  
  9. opener = urllib2.build_opener(RedirectHandler) 
  10. opener.open('http://www.google.cn'

Cookie

urllib2 對 Cookie 的處理也是自動的。如果需要得到某個 Cookie 項的值,可以這么做:

 

  1. import urllib2 
  2. import cookielib 
  3.  
  4. cookie = cookielib.CookieJar() 
  5. opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie)) 
  6. response = opener.open('http://www.google.com'
  7. for item in cookie: 
  8. if item.name == 'some_cookie_item_name'
  9. print item.value 

使用 HTTP 的 PUT 和 DELETE 方法

urllib2 只支持 HTTP 的 GET 和 POST 方法,如果要使用 HTTP PUT 和 DELETE ,只能使用比較低層的 httplib 庫。雖然如此,我們還是能通過下面的方式,使 urllib2 能夠發(fā)出 PUT 或 DELETE 的請求:

 

 
  1. import urllib2 
  2.  
  3. request = urllib2.Request(uri, data=data) 
  4. request.get_method = lambda: 'PUT' # or 'DELETE' 
  5. response = urllib2.urlopen(request) 

得到 HTTP 的返回碼

對于 200 OK 來說,只要使用 urlopen 返回的 response 對象的 getcode() 方法就可以得到 HTTP 的返回碼。但對其它返回碼來說,urlopen 會拋出異常。這時候,就要檢查異常對象的 code 屬性了:

 

 
  1. import urllib2 
  2. try
  3. response = urllib2.urlopen('http://restrict.web.com'
  4. except urllib2.HTTPError, e: 
  5. print e.code 
  6. Debug Log 

使用 urllib2 時,可以通過下面的方法把 debug Log 打開,這樣收發(fā)包的內(nèi)容就會在屏幕上打印出來,方便調(diào)試,有時可以省去抓包的工作

 

 
  1. import urllib2 
  2.  
  3. httpHandler = urllib2.HTTPHandler(debuglevel=1) 
  4. httpsHandler = urllib2.HTTPSHandler(debuglevel=1) 
  5. opener = urllib2.build_opener(httpHandler, httpsHandler) 
  6.  
  7. urllib2.install_opener(opener) 
  8. response = urllib2.urlopen('http://www.google.com'

PS: 借助urllib2抓取網(wǎng)站生成RSS

看了看OsChina的博客頁面,發(fā)現(xiàn)可以使用python來抓取.記得前段時間看到有人使用python的RSS模塊PyRSS2Gen生成了RSS.于是忍不住手癢自己試著實現(xiàn)了下,幸好還是成功了,下面代碼共享給大家.

首先需要安裝PyRSS2Gen模塊和BeautifulSoup模塊,pip安裝下就好了,我就不再贅述了.

下面貼出代碼

 

 
  1. # -*- coding: utf-8 -*- 
  2.  
  3.  
  4. from bs4 import BeautifulSoup 
  5. import urllib2 
  6.  
  7. import datetime 
  8. import time 
  9. import PyRSS2Gen 
  10. from email.Utils import formatdate 
  11. import re 
  12. import sys 
  13. import os 
  14. reload(sys) 
  15. sys.setdefaultencoding('utf-8'
  16.  
  17.  
  18.  
  19.  
  20. class RssSpider(): 
  21. def __init__(self): 
  22. self.myrss = PyRSS2Gen.RSS2(title='OSChina'
  23. link='http://my.oschina.net'
  24. description=str(datetime.date.today()), 
  25. pubDate=datetime.datetime.now(), 
  26. lastBuildDate = datetime.datetime.now(), 
  27. items=[] 
  28. self.xmlpath=r'/var/www/myrss/oschina.xml' 
  29.  
  30. self.baseurl="http://www.oschina.net/blog" 
  31. #if os.path.isfile(self.xmlpath): 
  32. #os.remove(self.xmlpath) 
  33. def useragent(self,url): 
  34. i_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) / 
  35. AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36", / 
  36. "Referer"'http://baidu.com/'
  37. req = urllib2.Request(url, headers=i_headers) 
  38. html = urllib2.urlopen(req).read() 
  39. return html 
  40. def enterpage(self,url): 
  41. pattern = re.compile(r'/d{4}/S/d{2}/S/d{2}/s/d{2}/S/d{2}'
  42. rsp=self.useragent(url) 
  43. soup=BeautifulSoup(rsp) 
  44. timespan=soup.find('div',{'class':'BlogStat'}) 
  45. timespan=str(timespan).strip().replace('/n','').decode('utf-8'
  46. match=re.search(r'/d{4}/S/d{2}/S/d{2}/s/d{2}/S/d{2}',timespan) 
  47. timestr=str(datetime.date.today()) 
  48. if match: 
  49. timestr=match.group() 
  50. #print timestr 
  51. ititle=soup.title.string 
  52. div=soup.find('div',{'class':'BlogContent'}) 
  53. rss=PyRSS2Gen.RSSItem( 
  54. title=ititle, 
  55. link=url, 
  56. description = str(div), 
  57. pubDate = timestr 
  58.  
  59. return rss 
  60. def getcontent(self): 
  61. rsp=self.useragent(self.baseurl) 
  62. soup=BeautifulSoup(rsp) 
  63. ul=soup.find('div',{'id':'RecentBlogs'}) 
  64. for li in ul.findAll('li'): 
  65. div=li.find('div'
  66. if div is not None: 
  67. alink=div.find('a'
  68. if alink is not None: 
  69. link=alink.get('href'
  70. print link 
  71. html=self.enterpage(link) 
  72. self.myrss.items.append(html) 
  73. def SaveRssFile(self,filename): 
  74. finallxml=self.myrss.to_xml(encoding='utf-8'
  75. file=open(self.xmlpath,'w'
  76. file.writelines(finallxml) 
  77. file.close() 
  78.  
  79.  
  80.  
  81. if __name__=='__main__'
  82. rssSpider=RssSpider() 
  83. rssSpider.getcontent() 
  84. rssSpider.SaveRssFile('oschina.xml')  

可以看到,主要是使用BeautifulSoup來抓取站點然后使用PyRSS2Gen來生成RSS并保存為xml格式文件.

順便共享下我生成的RSS地址

 

 
  1. http://104.224.129.109/myrss/oschina.xml 

大家如果不想折騰的話直接使用feedly訂閱就行了.

腳本我會每10分鐘執(zhí)行一次的.

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 高雄县| 古蔺县| 太谷县| 江北区| 赤水市| 盘山县| 德保县| 怀远县| 溆浦县| 中卫市| 洞头县| 霍山县| 秦安县| 门源| 阜新| 吴旗县| 苗栗市| 弥渡县| 酒泉市| 兴仁县| 苍山县| 乐昌市| 延吉市| 吉林省| 凤冈县| 剑川县| 板桥市| 平潭县| 德昌县| 原平市| 象山县| 德保县| 井冈山市| 罗甸县| 万州区| 长沙县| 静安区| 绍兴市| 临桂县| 伊宁县| 锡林郭勒盟|