Python網頁抓取urllib,urllib2,httplib[1]
前階段使用到ftp,寫了個工具腳本http://blog.csdn.net/wklken/article/details/7059423
最近需要抓網頁,看了下python抓取方式
需求:
抓取網頁,解析獲取內容
涉及庫:【重點urllib2】
urllib http://docs.python.org/library/urllib.html
urllib2 http://docs.python.org/library/urllib2.html
httplib http://docs.python.org/library/httplib.html
使用urllib:
1. 抓取網頁信息
urllib.urlopen(url[, data[, proxies]]) :
url: 表示遠程數據的路徑
data: 以post方式提交到url的數據
proxies:用於設置代理
urlopen返回對象提供方法:
- read() , readline() ,readlines() , fileno() , close() :這些方法的使用方式與文件對象完全一樣
- info():返回一個httplib.HTTPMessage對象,表示遠程服務器返回的頭信息
- getcode():返回Http狀態碼。如果是http請求,200請求成功完成;404網址未找到
- geturl():返回請求的url
使用:
- #!/usr/bin/python
- # -*- coding:utf-8 -*-
- # urllib_test.py
- # author:wklken
- # 2012-03-17 wklken#yeah.net
- import os
- import urllib
- url = "http://www.siteurl.com"
- def use_urllib():
- import urllib, httplib
- httplib.HTTPConnection.debuglevel = 1
- page = urllib.urlopen(url)
- print"status:", page.getcode() #200請求成功,404
- print"url:", page.geturl()
- print"head_info:\n", page.info()
- print"Content len:", len(page.read())
附帶的其他方法:(主要是url編碼解碼)
- urllib.quote(string[, safe]):對字符串進行編碼。參數safe指定了不需要編碼的字符
- urllib.unquote(string) :對字符串進行解碼
- urllib.quote_plus(string [ , safe ] ) :與urllib.quote類似,但這個方法用'+'來替換' ',而quote用'%20'來代替' '
- urllib.unquote_plus(string ) :對字符串進行解碼
- urllib.urlencode(query[, doseq]):將dict或者包含兩個元素的元組列表轉換成url參數。例如 字典{'name': 'wklken', 'pwd': '123'}將被轉換為"name=wklken&pwd=123"
- urllib.pathname2url(path):將本地路徑轉換成url路徑
- urllib.url2pathname(path):將url路徑轉換成本地路徑
使用:
- def urllib_other_functions():
- astr = urllib.quote('this is "K"')
- print astr
- print urllib.unquote(astr)
- bstr = urllib.quote_plus('this is "K"')
- print bstr
- print urllib.unquote(bstr)
- params = {"a":"1", "b":"2"}
- print urllib.urlencode(params)
- l2u = urllib.pathname2url(r'd:\a\test.py')
- print l2u
- print urllib.url2pathname(l2u)
2. 下載遠程數據
urlretrieve方法直接將遠程數據下載到本地
urllib.urlretrieve(url[, filename[, reporthook[, data]]]):
filename指定保存到本地的路徑(若未指定該,urllib生成一個臨時文件保存數據)
reporthook回調函數,當連接上服務器、以及相應的數據塊傳輸完畢的時候會觸發該回調
data指post到服務器的數據
該方法返回一個包含兩個元素的元組(filename, headers),filename表示保存到本地的路徑,header表示服務器的響應頭。
- def callback_f(downloaded_size, block_size, romote_total_size):
- per = 100.0 * downloaded_size * block_size / romote_total_size
- if per > 100:
- per = 100
- print"%.2f%%"% per
- def use_urllib_retrieve():
- import urllib
- local = os.path.join(os.path.abspath("./"), "a.html")
- print local
- urllib.urlretrieve(url,local,callback_f)
下一篇:httplib
轉載請注明出處:http://blog.csdn.net/wklken
Python網頁抓取urllib,urllib2,httplib[2]
上一篇使用urllib抓取 Python網頁抓取urllib,urllib2,httplib[1]
使用httplib抓取:
表示一次與服務器之間的交互,即請求/響應
httplib.HTTPConnection ( host [ , port [ ,strict [ , timeout ]]] )
host表示服務器主機
port為端口號,默認值為80
strict的 默認值為false, 表示在無法解析服務器返回的狀態行時(status line) (比較典型的狀態行如: HTTP/1.0 200 OK ),是否拋BadStatusLine 異常
可選參數timeout 表示超時時間。
HTTPConnection提供的方法:
- HTTPConnection.request ( method , url [ ,body [ , headers ]] )
調用request 方法會向服務器發送一次請求
method 表示請求的方法,常用有方法有get 和post ;
url 表示請求的資源的url ;
body 表示提交到服務器的數據,必須是字符串(如果method是”post”,則可以把body 理解為html 表單中的數據);
headers 表示請求的http 頭。
- HTTPConnection.getresponse ()
獲取Http 響應。返回的對象是HTTPResponse 的實例,關於HTTPResponse 在下面會講解。
- HTTPConnection.connect ()
連接到Http 服務器。
- HTTPConnection.close ()
關閉與服務器的連接。
- HTTPConnection.set_debuglevel ( level )
設置高度的級別。參數level 的默認值為0 ,表示不輸出任何調試信息。
httplib.HTTPResponse
-HTTPResponse表示服務器對客戶端請求的響應。往往通過調用HTTPConnection.getresponse()來創建,它有如下方法和屬性:
-HTTPResponse.read([amt])
獲取響應的消息體。如果請求的是一個普通的網頁,那么該方法返回的是頁面的html。可選參數amt表示從響應流中讀取指定字節的數據。
-HTTPResponse.getheader(name[, default])
獲取響應頭。Name表示頭域(header field)名,可選參數default在頭域名不存在的情況下作為默認值返回。
-HTTPResponse.getheaders()
以列表的形式返回所有的頭信息。
- HTTPResponse.msg
獲取所有的響應頭信息。
-HTTPResponse.version
獲取服務器所使用的http協議版本。11表示http/1.1;10表示http/1.0。
-HTTPResponse.status
獲取響應的狀態碼。如:200表示請求成功。
-HTTPResponse.reason
返回服務器處理請求的結果說明。一般為”OK”
使用例子:
- #!/usr/bin/python
- # -*- coding:utf-8 -*-
- # httplib_test.py
- # author:wklken
- # 2012-03-17 wklken#yeah.net
- def use_httplib():
- import httplib
- conn = httplib.HTTPConnection("www.baidu.com")
- i_headers = {"User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1) Gecko/20090624 Firefox/3.5",
- "Accept": "text/plain"}
- conn.request("GET", "/", headers = i_headers)
- r1 = conn.getresponse()
- print"version:", r1.version
- print"reason:", r1.reason
- print"status:", r1.status
- print"msg:", r1.msg
- print"headers:", r1.getheaders()
- data = r1.read()
- print len(data)
- conn.close()
- if __name__ == "__main__":
- use_httplib()
Python網頁抓取urllib,urllib2,httplib[3]
使用urllib2,太強大了
試了下用代理登陸拉取cookie,跳轉抓圖片......
文檔:http://docs.python.org/library/urllib2.html
直接上demo代碼了
包括:直接拉取,使用Reuqest(post/get),使用代理,cookie,跳轉處理
- #!/usr/bin/python
- # -*- coding:utf-8 -*-
- # urllib2_test.py
- # author: wklken
- # 2012-03-17 wklken@yeah.net
- import urllib,urllib2,cookielib,socket
- url = "http://www.testurl....."#change yourself
- #最簡單方式
- def use_urllib2():
- try:
- f = urllib2.urlopen(url, timeout=5).read()
- except urllib2.URLError, e:
- print e.reason
- print len(f)
- #使用Request
- def get_request():
- #可以設置超時
- socket.setdefaulttimeout(5)
- #可以加入參數 [無參數,使用get,以下這種方式,使用post]
- params = {"wd":"a","b":"2"}
- #可以加入請求頭信息,以便識別
- i_headers = {"User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1) Gecko/20090624 Firefox/3.5",
- "Accept": "text/plain"}
- #use post,have some params post to server,if not support ,will throw exception
- #req = urllib2.Request(url, data=urllib.urlencode(params), headers=i_headers)
- req = urllib2.Request(url, headers=i_headers)
- #創建request后,還可以進行其他添加,若是key重復,后者生效
- #request.add_header('Accept','application/json')
- #可以指定提交方式
- #request.get_method = lambda: 'PUT'
- try:
- page = urllib2.urlopen(req)
- print len(page.read())
- #like get
- #url_params = urllib.urlencode({"a":"1", "b":"2"})
- #final_url = url + "?" + url_params
- #print final_url
- #data = urllib2.urlopen(final_url).read()
- #print "Method:get ", len(data)
- except urllib2.HTTPError, e:
- print"Error Code:", e.code
- except urllib2.URLError, e:
- print"Error Reason:", e.reason
- def use_proxy():
- enable_proxy = False
- proxy_handler = urllib2.ProxyHandler({"http":"http://proxyurlXXXX.com:8080"})
- null_proxy_handler = urllib2.ProxyHandler({})
- if enable_proxy:
- opener = urllib2.build_opener(proxy_handler, urllib2.HTTPHandler)
- else:
- opener = urllib2.build_opener(null_proxy_handler, urllib2.HTTPHandler)
- #此句設置urllib2的全局opener
- urllib2.install_opener(opener)
- content = urllib2.urlopen(url).read()
- print"proxy len:",len(content)
- class NoExceptionCookieProcesser(urllib2.HTTPCookieProcessor):
- def http_error_403(self, req, fp, code, msg, hdrs):
- return fp
- def http_error_400(self, req, fp, code, msg, hdrs):
- return fp
- def http_error_500(self, req, fp, code, msg, hdrs):
- return fp
- def hand_cookie():
- cookie = cookielib.CookieJar()
- #cookie_handler = urllib2.HTTPCookieProcessor(cookie)
- #after add error exception handler
- cookie_handler = NoExceptionCookieProcesser(cookie)
- opener = urllib2.build_opener(cookie_handler, urllib2.HTTPHandler)
- url_login = "https://www.yourwebsite/?login"
- params = {"username":"user","password":"111111"}
- opener.open(url_login, urllib.urlencode(params))
- for item in cookie:
- print item.name,item.value
- #urllib2.install_opener(opener)
- #content = urllib2.urlopen(url).read()
- #print len(content)
- #得到重定向 N 次以后最后頁面URL
- def get_request_direct():
- import httplib
- httplib.HTTPConnection.debuglevel = 1
- request = urllib2.Request("http://www.google.com")
- request.add_header("Accept", "text/html,*/*")
- request.add_header("Connection", "Keep-Alive")
- opener = urllib2.build_opener()
- f = opener.open(request)
- print f.url
- print f.headers.dict
- print len(f.read())
- if __name__ == "__main__":
- use_urllib2()
- get_request()
- get_request_direct()
- use_proxy()
- hand_cookie()
Python urllib2遞歸抓取某個網站下圖片
需求:
抓取某個網站下圖片
可定義 圖片保存路徑,最小圖片大小域值,遍歷深度,是否遍歷到外站,抓取並下載圖片
使用庫:
urllib http://docs.python.org/library/urllib.html【下載】
urllib2 http://docs.python.org/library/urllib2.html【抓取】
urlparse http://docs.python.org/library/urlparse.html【url切分用到】
sgmllib http://docs.python.org/library/sgmllib.html【html解析用到】
代碼:
- #!/usr/bin/python
- # -*- coding:utf-8 -*-
- # author: wklken
- # 2012-03-17 wklken@yeah.net
- #1實現url解析 #2實現圖片下載 #3優化重構
- #4多線程 尚未加入
- import os,sys,urllib,urllib2,urlparse
- from sgmllib import SGMLParser
- img = []
- class URLLister(SGMLParser):
- def reset(self):
- SGMLParser.reset(self)
- self.urls=[]
- self.imgs=[]
- def start_a(self, attrs):
- href = [ v for k,v in attrs if k=="href"and v.startswith("http")]
- if href:
- self.urls.extend(href)
- def start_img(self, attrs):
- src = [ v for k,v in attrs if k=="src"and v.startswith("http") ]
- if src:
- self.imgs.extend(src)
- def get_url_of_page(url, if_img = False):
- urls = []
- try:
- f = urllib2.urlopen(url, timeout=1).read()
- url_listen = URLLister()
- url_listen.feed(f)
- if if_img:
- urls.extend(url_listen.imgs)
- else:
- urls.extend(url_listen.urls)
- except urllib2.URLError, e:
- print e.reason
- return urls
- #遞歸處理頁面
- def get_page_html(begin_url, depth, ignore_outer, main_site_domain):
- #若是設置排除外站 過濾之
- if ignore_outer:
- ifnot main_site_domain in begin_url:
- return
- if depth == 1:
- urls = get_url_of_page(begin_url, True)
- img.extend(urls)
- else:
- urls = get_url_of_page(begin_url)
- if urls:
- for url in urls:
- get_page_html(url, depth-1)
- #下載圖片
- def download_img(save_path, min_size):
- print"download begin..."
- for im in img:
- filename = im.split("/")[-1]
- dist = os.path.join(save_path, filename)
- #此方式判斷圖片的大小太浪費了
- #if len(urllib2.urlopen(im).read()) < min_size:
- # continue
- #這種方式先拉頭部,應該好多了,不用再下載一次
- connection = urllib2.build_opener().open(urllib2.Request(im))
- if int(connection.headers.dict['content-length']) < min_size:
- continue
- urllib.urlretrieve(im, dist,None)
- print"Done: ", filename
- print"download end..."
- if __name__ == "__main__":
- #抓取圖片首個頁面
- url = "http://www.baidu.com/"
- #圖片保存路徑
- save_path = os.path.abspath("./downlaod")
- ifnot os.path.exists(save_path):
- os.mkdir(save_path)
- #限制圖片最小必須大於此域值 單位 B
- min_size = 92
- #遍歷深度
- max_depth = 1
- #是否只遍歷目標站內,即存在外站是否忽略
- ignore_outer = True
- main_site_domain = urlparse.urlsplit(url).netloc
- get_page_html(url, max_depth, ignore_outer, main_site_domain)
- download_img(save_path, min_size)
后續可以優化
1.使用多線程優化下載,目前多層遍歷不夠速度
2.使用BeautifulSoup寫一個版本
3.加入圖形界面......
2012-03-17
wklken
轉載請注明出處:http://blog.csdn.net/wklken