以下網頁有102個圖標,如何一次性爬?。?/p>
http://www.pp3.cn/icon/size/16_16/2011/1128/831.html
試試以下小程序:
import re
import urllib.request
import os
#1 抓取網頁(網頁上有圖片地址)
url = 'http://www.pp3.cn/icon/size/qita/2011/1128/758.html'
req = urllib.request.urlopen(url)
buf = req.read()
req.close()
#2 獲取圖片地址
# 下面4句截取url的前半截,如http://www.pp3.cn(一些圖片是相對地址)
i = url.find("/",9)
url0 = url
if i > 0 :
url0 = url[:i]
buf = buf.decode('gb2312') # 有些網頁編碼是utf-8,要一致
listurl = re.findall(r'img src=.[^\'\"]+\.png',buf)
for i in range(len(listurl)): # 把字符img src="去掉
listurl[i]=listurl[i].replace('img src="',"")
if not re.match("http",listurl[i]): # 如果是相對地址,加上上面提取的基地址
listurl[i]=url0 + listurl[i]
print(listurl[i]) # 將圖片地址列表打印一下
#3 抓取圖片并保存到本地
fpath = "D:\\pic2\\"
if not os.path.isdir(fpath):
os.mkdir(fpath)
i = 0
for url in listurl:
f=open(fpath + str(i)+'.png','wb')
req = urllib.request.urlopen(url)
buf = req.read()
f.write(buf)
f.close()
i+=1
有四個關鍵點:
1 網頁的編碼:有的是GB2312,有的是utf-8。
2 有的網站服務器做了反爬蟲設置,需要寫較復雜的代碼來繞過。
3 圖片網址正則表達式的設置。如上述的
r'img src=.[^\'\"]+\.png'
圖片的HTML的寫法:
img src='http//…/picPath/…/.png'
img src='http//…/picPath/…/.jpg'
img src="http//…/picPath/…/.jpg"
img src="picPath/…/.jpg"
要通過適當的正則表達式來構建上述字符串表示規律。
3.1 圓點“.”表示除'\n'以外的任意字符。上述可以表示單引號或雙引號,如果沒有其它字符,如在引用前還有一個字符,可多寫一個圓點.。
3.2 “[^\'\"]+”表示一串除了單引號或雙引號以外的任意數量的其它字符。直到遇到“\.png”為止(可能出現貪婪匹配)?!癧]”表示列舉,“^”表示非,排除后面緊跟的字符;“\”表示轉義,轉義是指轉變原本的含義,單引號和雙引號原本是用來界定字符的,用轉義符來放棄這個用途,用做普通字符。加號“+”表示一個或多個前面的字符表示。
3.3 "\.png"表示圓點.和圖片的類型png。
上面說到貪婪匹配,要設置為非貪婪匹配,用小括號分組加一個問號即可:
reg = r'img src=.([^\'\"]+\.png)?'
如果出現問題,可以相看原網頁的圖片地址編寫格式及規律,簡單化處理。
如圖片地址都有如下規律,
http://www.pp3.cn/uploads/allimg/111128/1-11112…….png
可將正則表達式簡單寫為:
http://www.pp3.cn/uploads/allimg/111128/1-11112\S*.png
“/S*”表示任意數量非空白字符。
如果有多個網頁,可以將上述代碼寫成函數形式,循環調用:
import re # 正則表達式
import urllib.request # 從服務器請求返回資源
import os # 文件和目錄操作
import socket # 套接字操作
#socket.setdefaulttimeout(20) # 設置socket層的超時時間為20秒
def gethtml(url): #1 抓取網頁html內容
with urllib.request.urlopen(url) as req:
buf = req.read()
return buf
def getImg(buf,codec,fpath,rege): #2 從html篩選圖片地址到list
# 下面4句截取url的前半截,如http://www.pp3.cn(一些圖片是相對地址)
i = url.find("/",9)
url0 = url
if i > 0 :
url0 = url[:i]
buf = buf.decode(codec)
listurl = re.findall(reg,buf) #reg是正則表達式
print("準備下載圖片數量:",len(listurl))
for i in range(len(listurl)):
#listurl[i]=listurl[i].replace('img src="',"") # 把字符img src="去掉
if not re.match("http",listurl[i]):
listurl[i]=url0 + listurl[i]
print(listurl[i])
#3 抓取圖片并保存到本地
if not os.path.isdir(fpath):
os.mkdir(fpath)
i = 0
'''
for imgurl in listurl:
urllib.request.urlretrieve(imgurl,fpath + str(i)+'.jpg')
i+=1
'''#下面的操作方式要快一點
for imgurl in listurl:
f=open(fpath + str(i)+'.jpg','wb') # 新建空白圖片文件
req = urllib.request.urlopen(imgurl) # 獲取網頁圖片文件
buf = req.read() # 讀取網站上圖片文件內容
f.write(buf) # 將網站上圖片內容寫入新建的圖片文件
f.close()
i+=1
# 四處內容需要確認:1 網頁url; 2 網頁編碼UTF-8或gb2312;
# 3 圖片擴展名jpg或png(兩處); 4 保存的文件夾
codec = 'gb2312'
reg = r'img src=.([^\'\"]+\.png)?'
webpages = ['http://www.pp3.cn/icon/size/qita/2011/1128/758.html', # 需提取圖片的網址可寫到列表內
'http://www.pp3.cn/icon/size/32_32/2011/1128/768.html'
]
i = 0
for url in webpages:
buf = gethtml(url)
fpath = "D:\\" + str(i) +"\\"
print(getImg(buf,codec,fpath,reg)) # 函數循環調用
i+=1
url = 'http://culture.ifeng.com/c/7vm9bFrvQpl'
codec = 'utf-8'
buf = gethtml(url)
reg = r'img src=..([^\'\"]+\.jpeg)?'
fpath = 'D:\\A\\'
print(getImg(buf,codec,fpath,reg)) # 函數單獨調用
圖片格式不同的較靈活的寫法:
import re
import urllib.request
import os
from itertools import islice # 跳過可迭代對象的開始部分
# fpath = "D:\\pic2\\"
# 分析網頁文本、提到圖片超鏈接到list,逐一將list項保存到圖片文件
# ① 要注意網頁的字符編碼,可在網頁查看
# ② 要注意網站圖片的url格式規律
# ③ 要注意圖片的擴展名
# ④ 一次老是抓取不成功,原因是第三張無法打開,后跳過
#"""
# 1 獲取網頁文本
url = 'http://www.pp3.cn/icon/size/16_16/2011/1128/831.html'
#url = 'http://www.pp3.cn/icon/size/16_16/2011/1128/835.html'
# 1.1 url沒加header的寫法
req = urllib.request.urlopen(url)
buf = req.read()
req.close()
# 1.2 在urllib中添加headers不同的寫法,需要headers是字典或元組
"""
headers = { # 如有反爬,可添加網頁自己的header
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
}
req = urllib.request.Request(url=url,headers=headers)
file = urllib.request.urlopen(req)
buf = file.read()
"""
#2 多網頁文本中解析出圖片地址
i = url.find("/",9) # 本句及下面三句截取url的前半截
url2 = url
if i > 0 :
url2 = url[:i]
#buf = buf.decode('UTF-8')
buf = buf.decode('gb2312')
#picType = '.jpg'
#picType = '.jpeg'
picType = '.png'
#picType = '.gif'
#listurl = re.findall(r'http:.[^"]+\.jpg',buf)
if picType == '.jpg' :
listurl = re.findall(r'img src=.([^\"^\']+\.jpg)?',buf)
if picType == '.jpeg' :
listurl = re.findall(r'img src=.([^\"^\']+\.jpeg)?',buf)
if picType == '.png' :
listurl = re.findall(r'img src=.([^\"^\']+\.png)?',buf)
if picType == '.gif' :
listurl = re.findall(r'img src=.([^\"^\']+\.gif)?',buf)
for i in range(len(listurl)): # 把字符img src="去掉
listurl[i]=listurl[i].replace('img src="',"")
if not re.match("http",listurl[i]):
listurl[i]=url2 + listurl[i]
print(listurl[i])
#"""
"""
# 已知圖片url,只是序號不同
listurl = []
strs = "http://www.graphiscnn.com/evahbcms/upload/image/196/00"
for x in range(2,55):
listurl.insert(x,strs+str(x)+".jpg")
"""
#3 抓取圖片并保存到本地
i = 1
fpath = "D:\\pic3\\"
if not os.path.isdir(fpath):
os.mkdir(fpath)
#for url in listurl: # 列表的第三張無法打開,導致失敗
for url in islice(listurl, 4, None):
f=open(fpath + str(i)+picType,'wb')
req = urllib.request.urlopen(url)
buf = req.read()
f.write(buf)
print(i,picType)
f.close()
i+=1
"""
# UnicodeEncodeError: 'UCS-2' codec can't encode characters
# in position 73-73: Non-BMP character not supported in Tk
# 爬取的HTML頁面中包含了Unicode下無法識別的字符,添加標識為①-③的三行代碼
import requests
import sys # ①
non_bmp_map = dict.fromkeys(range(0x10000,sys.maxunicode + 1),0xfffd) # ②
url = 'https://p.51vv.com/vp/kws2X4IT'
html = requests.get(url,headers=headers)
print(html.request.headers)
html = str(html.text).translate(non_bmp_map) # ③
print(html)
"""
運行:
提取到的圖片:
End
格語法:
注意:顏色使用格式有三種:rgb(x,x,x) #xxxxxx colorname
<table width=""></table>指定表格的寬度大小(使用數字pixel或%)
<table border=""></table>設定表格邊框大小(使用數字pixel)
<table align=""></table>表格位置,置左,為默認值
align屬性:left(左對齊表格,默認值)、right(右對齊表格)、center(居中對齊表格)
<table bgcolor=""></table>設定表格的背景顏色
<table cellpadding=""></table>指定內容與網格線之間的間距(使用數字pixel或%)
<table cellspacing=""></table>指定網格線與網格線之間的距離(使用數字pixel或%)
<table border="1" cellspacing="0" cellpadding="0">
通常表格, 這兩個參數都設置為 0 。
<table rules="rows"></table>規定內側邊框的哪個部分是可見的。(兼容性差)
rules屬性:none 沒有線條。
groups 位于行組和列組之間的線條。
rows 位于行之間的線條。
cols 位于列之間的線條。
all 位于行和列之間的線條。
<table summary="Monthly savings for the Flintstones family"></table>
定義了表格內容的摘要:
表格結構:
在使用表格進行布局時, 可以將表格劃分為頭部、主體和頁腳, 具體如下所示:
<thead></thead>:用于定義表格的頭部, 必須位于<table></table>標記中, 一般包含網頁的logo和導航等頭部信息。
<tfoot></tfoot>:用于定義表格的頁腳, 位于<table></table>標記中<thead></thead>標記之后, 一般包含網頁底部的企業信息等。
<tbody></tbody>:用于定義表格的主體, 位于<table></table>標記中<tfoot></tfoot>標記之后, 一般包含網頁中除頭部和底部之外的其他內容。
注意:在沒有<tbody></tbody>比較的情況下, 瀏覽器會自動添加<tbody></tbody>標記。
<table bordercolor=""></table>設定表格邊框的顏色
<table cols=""></table>指定表格的欄數
<table height=""></table>指定表格的高度大小(使用數字)
<table background=""></table>背景圖片的URL=就是路徑網址(默認是repeat:水平和垂直方向重復)
<table bordercolordark=""></table>設定表格暗邊框的顏色
<table bordercolorlight=""></table>設定表格亮邊框的顏色
<tr align=""></tr> 定義表格行的內容對齊方式。
align屬性值:right、left、center、justify、char
<tr bgcolor=""></tr> 規定表格行的背景顏色。
<tr valign=""></tr> 規定表格行中內容的垂直對齊方式。
valign屬性值right、left、center、justify、char
<td colspan=""></td>指定儲存格合并欄的欄數(使用數字)
<td rowspan=""></td>指定儲存格合并列的列數(使用數字)
<td align=""></td> 調整表格字段之左右對齊
<td bgcolor=""></td> 設定表格字段之背景顏色
<td colspan="" rowspan=""></td> 表格字段的合并
<td valign=""></td> 調整表格字段之上下對齊
<td width=""></td> 調整表格字段寬度
<td nowrap="nowrap"></td> 規定表格單元格中的內容不換行(注意只有一個值:nowrap)
<caption></caption>為表格加上標題
<caption align="">設定表格標題位置
align屬性:left, center(默認值), right
<th></th> 定義表頭(粗體居中)
細表格邊框
<table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="158" height="68">
<tr>
<td width="158" height="68"></td>
</tr>
</table>
表格創建后瀏覽器會自動添加<tbody>標簽
一篇文章中,小海前端(頭條號)為小伙伴們介紹了CSS3中新增的border-image屬性,該屬性主要用于為容器的邊框添加圖片。本篇文章,繼續為大家講解該屬性的用法和CSS3中對該屬性的一些細節要求。
尚未閱讀上一篇文章的小伙伴請先閱讀上一篇文章,上一篇文章講解了border-image屬性及其派生屬性的基礎用法。
承接文章:為容器的邊框添加圖片,CSS3新增的邊框圖片屬性,一種新穎的用法
技術等級:中級 | 適合有一定的CSS基礎的人士閱讀。
該組屬性的兼容性暫時還不是特別好,建議大家使用火狐瀏覽器(Firefox)來嘗試該屬性的各個效果。
希望收藏了這篇文章的你同時也可以關注一下“小海前端”的頭條號,因為這些文章都是連載的,并且是經過系統的歸納和總結的。塌下心來認真閱讀,你一定會學到對你有用的知識。
本篇文章涉及到的CSS3屬性問題:
border-image-slice屬性的使用細節
border-outset屬性的用法
border-image-width屬性和border-width屬性的區別
border-image屬性和border屬性的沖突性
各個瀏覽器內核的兼容性
一、border-image-slice屬性的使用細節:
上一篇文章中講到,border-image-slice是用來設置邊框圖片的切片屬性的。該屬性的取值為一個不帶單位的數值,默認單位為像素,但是不用書寫px。該屬性設置的數值可以將邊框圖片劃分為9個區域,并貼到邊框的9個不同位置。
這里還以上一篇文章中寬度和高度均為90像素的圖片為例,該圖片存放在一個名為images的文件夾中,圖片的文件名為ball.jpg,圖片中每個圓形的直徑均為30像素。
素材圖 ball.jpg
對于該屬性,CSS3對于它的使用方法還有以下幾個細節要求:
當切片的上下偏移之和大于等于圖像的高度,且左右偏移之和大于等于圖像的寬度。則容器只有四個角可以獲得邊框圖片的切片,而容器的邊無法獲得任何圖片。
CSS代碼如下所示:
border-image:url(../images/ball.jpg) 60 70 50 30/30px round
上述代碼指出,上切片尺寸為60像素,右切片尺寸為70像素,下切片尺寸為50像素,左切片尺寸為30像素。上下切片的偏移之和為110像素,左右切片的偏移之和為100像素,這兩個值均超過了圖片90像素的寬高尺寸。因此只有容器的四個角可以得到邊框圖像。最終效果如下圖所示:
實體效果圖
當切片的上下偏移量都大于等于圖像的高度,且左右偏移量都大于等于圖像的寬度。則容器的四個角可以獲得完整的邊框圖像。
CSS代碼如下所示:
border-image:url(../images/ball.jpg) 90 100 120 130/30px round
上述代碼指出,上切片尺寸為90像素,右切片尺寸為100像素,下切片尺寸為120像素,左切片尺寸為130像素。每一個方向的切片偏移量均大于等于圖片90像素的寬度和高度值。因此容器的四個角可以獲得完整的邊框圖像。同樣,邊依然無法得到任何切片圖像。
最終效果如下圖所示:
實體效果圖
border-image-slice屬性還有一個可以放在切片數量后面的取值。當具有該取值并設置為“fill”時,邊框圖片中5號圓形就會顯示在容器的內部。如果沒有該取值,邊框圖片中5號圓形就不會顯示在容器內部。
CSS代碼如下所示:
border-image:url(../images/ball.jpg) 30 fill/30px round
最終效果如下圖所示:
實體效果圖
二、border-outset屬性的用法:
該屬性用來對邊框圖像實現向外擴張的效果。該屬性的取值為帶有單位的數值。同時該屬性也是可以結合border-image屬性單獨使用的。
CSS代碼如下所示:
border-image:url(../images/ball.jpg) 30/30px round
border-outset:30px;
上述代碼會讓邊框圖像在顯示的同時向外擴張30像素。請小伙伴們自行操作并嘗試。
三、border-image-width屬性和border-width屬性的區別:
border-width屬性可以單獨使用,適用于設置具有顏色的邊框寬度。
border-image-width屬性不可以單獨使用,必須在border-image屬性取值內部固定的位置處使用。該屬性主要用于設置具有圖像的邊框寬度。
這兩個屬性是可以同時使用的。
當容器內部具備文本內容時,我們發現,文本內容出現在了邊框圖片的位置處。為了方便小伙伴們觀察,我把文本內容調整成了黃色。如下圖的左側部分。
實體效果圖
此時調整border-width屬性,為了讓邊框寬度生效,還需要設置邊框樣式border-style。為了不讓容器的大小發生變化,添加box-sizing屬性。為了便于查看,我把文本內容調整成了紅色。如上圖右側部分。
CSS代碼如下所示:
border-image: url(../images/ball.jpg) 30/30px round;
border-width: 30px;
border-style: solid;
box-sizing: border-box;
color:#ff0000;
四、border-image屬性和border屬性的沖突性:
CSS3規定,帶有顏色的邊框和邊框圖片不得同時存在,并且當border-image屬性和border屬性同時存在時,border-image是不起作用的。
CSS代碼如下所示。
border-image:url(../images/ball.jpg) 30/30px round;
border:solid 10px #ff5857;
上述代碼執行后,容器會帶有10像素的邊框,而不帶有邊框圖片。小伙伴們可以自行嘗試。
五、各個瀏覽器內核的兼容性:
CSS3的屬性中還有許多都是瀏覽器不能完全兼容的,有的屬性兼容部分瀏覽器,有的屬性被瀏覽器部分兼容。那么,要對所有的瀏覽器都得到相同的外觀,應該如何處理呢?
可以采用為CSS屬性的兼容性前綴來解決這個問題。
-ms-,適用于具有Trident內核的IE系列瀏覽器。
-webkit-,適用于具有webkit內核的瀏覽器,例如Safari瀏覽器、360安全瀏覽器等。
-moz-,適用于Firefox瀏覽器。
-o-,適用于Opera瀏覽器。
因此,border-image屬性要實現瀏覽器全兼容可以使用下列代碼:
border-image:url(../images/ball.jpg) 30/30px round
-webkit-border-image:url(../images/ball.jpg) 30/30px round
-moz-border-image:url(../images/ball.jpg) 30/30px round
-o-border-image:url(../images/ball.jpg) 30/30px round
-ms-border-image:url(../images/ball.jpg) 30/30px round
不過通過實際操作,我發現border-image屬性即使加上了瀏覽器兼容性前綴,也不能達到滿意的效果。CSS3中還有許多屬性都不能達到最滿意的兼容性,我們只能等待CSS3完備的計劃出臺,并盡快得到大部分瀏覽器廠商的支持和認可。
在頭條上發表的這些文章都是從前端開發的基礎開始一步一步講起的。我非常希望能有更多的前端開發初學者通過我寫的文章,逐步學到一定的知識,甚至慢慢有了入門的感覺。這些文章都是我這幾年教學過程中的經驗,每寫一篇時我都盡量把握好措辭,用簡單易懂的語言描述,同時精心設計版面,讓版面更加豐富,激發閱讀興趣。所以,每一篇文章可能篇幅不長,但是都要耗費小海老師很久的時間。
希望收藏了這篇文章的你同時也可以關注一下“小海前端”的頭條號,因為這些文章都是連載的,并且是經過系統的歸納和總結的。塌下心來認真閱讀,你一定會學到對你有用的知識。
關注“小海前端”,我會繼續為大家奉上更加深入的前端開發文章,也希望更多的初學者跟著學下去,我們共同將前端開發的路努力堅持的走下去。
下一篇文章中,小海前端(頭條號)會為小伙伴們講解CSS3中實現多列布局的屬性。這組屬性解決了在CSS2時必須要對容器進行浮動才能在一行內顯示多列的問題。希望小伙伴們不要錯誤。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。