目標地址: http://image.baidu.com/
輸入美女

分析網址
元網址見圖

粘貼過來卻如下
(在這里你會看到,明明在瀏覽器URL欄看到的是中文,但是復制url,粘貼到記事本或代碼里面,就會變成如下這樣???)
https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1610771025434_R&pv=&ic=&nc=1&z=&hd=&latest=©right=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word=%E7%BE%8E%E5%A5%B3
在很多網站的URL中對一些get的引數或關鍵字進行編碼,所以我們復制出來的時候,會出現問題,
URL的編碼和解碼
import urllib
from urllib import parse
import urllib.request
data = {'word': '美女'}
# Python3的urlencode需要從parse中呼叫,可以看到urlencode()接受的是一個字典
print(urllib.parse.urlencode(data))
# 通過urllib.request.unquote()方法,把URL編碼字串,轉換回原先字串
print(urllib.request.unquote('word=%E7%BE%8E%E5%A5%B3'))
分析源代碼
F12或者頁面上右鍵審查元素,打開以后,定位到圖片的位置

復制下面這個網址
注意有轉義字符
imgurl="https:\/\/ss0.bdstatic.com\/70cFvHSh_Q1YnxGkpoWK1HF6hhy\/it\/u=2718853745,1288801299&fm=214&gp=0.jpg"
然后在當前網頁的空白地方右鍵:查看網頁源代碼
使用快捷鍵CTRl+F
查找(我這里 輸入 gp=0.jpg 通過輸入圖片網址最后幾個字符來定位圖片)

這個圖片怎么有很多地址,到呼叫哪個呢?可以看到有thumbURL,objURL等等,
通過分析可以知道,前面兩個是縮小的版本,hover是滑鼠移動過后顯示的版本,objURL對應的那個地址,應該是我們需要的,不信可以打開這幾個網址看看,發現obj那個最大最清晰,

撰寫正則運算式或者XPath運算式
pic_url = re.findall(’“objURL”:"(.*?)",’,html,re.S)
objurl后面的,全匹配
找到本機電腦網路的headers
有的時候,我們無法爬取一些網頁,會出現403錯誤,因為這些網頁為了防止別人惡意采集資訊所以進行了一些反爬蟲的設定,
我們可以設定一些Headers資訊,模擬成瀏覽器去訪問這些網站,就能解決這個問題,
首先,單擊網頁中的百度一下,即讓網頁發生一個動作,下方視窗出現了很多資料,如圖,

此時單擊圖中的www.baidu.com,出現如圖
在Headers,往下拖動,找到User-agent
這一串資訊就是我們下面模擬瀏覽器用到的資訊,復制出來,

所有代碼
語言python
from urllib.parse import quote
import string
import re
from urllib import request
import urllib.request
word = input('關鍵詞:')
url = 'http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + word + '&ct=201326592&v=flip'
url = quote(url, safe=string.printable)# # 解決ascii編碼報錯問題,不報錯則可以注釋掉
#模擬成瀏覽器
headers=("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3947.100 Safari/537.36")
opener=urllib.request.build_opener()
opener.addheaders=[headers]
#將opener安裝為全域
urllib.request.install_opener(opener)
#讀取網頁
url_request=request.Request(url)
url_response = request.urlopen(url_request,timeout=10) # 請求資料,可以和上一句合并.表示一次http訪問請求的時間最多10秒,一旦超過,本次請求中斷,但是不進入下一條,而是繼續重復請求這一條
html = url_response.read().decode('utf-8') # 加編碼,重要!轉換為字串編碼,read()得到的是byte格式的,
jpglist = re.findall('"thumbURL":"(.*?)",',html,re.S) #re.S將字串作為整體,在整體中進行匹配,,thumbURL可以匹配其他格式的圖
print(len(jpglist))
n = 1
for each in jpglist:
print(each)
try:
request.urlretrieve(each,'D:\\deeplearn\\xuexicaogao\\圖片\\%s.jpg' %n) #爬下載的圖片放置在提前建好的檔案夾里
except Exception as e:
print(e)
finally:
print('下載完成,')
n+=1
if n==90:
break
print('結束')
代碼決議
爬蟲報錯UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 45-47: ordinal not…
原因 python 默認的編碼是ascii,當程式中出現非ascii編碼時,python的處理常常會報這樣的錯UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0x?? in position 1: ordinal not in range(128),python沒辦法處理非ascii編碼的,此時需要自己設定將python的默認編碼,一般設定為utf8的編碼格式,
使用urllib.parse.quote進行轉換,
結果檔案夾

代碼版本2
語言python
import urllib
import urllib.request
from urllib.parse import quote
import re
import os
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
"referer": "https://image.baidu.com"
}
print("****************************************************************************************")
keyword = input("請輸入要下載的圖片:")
last_dir = "C://Users//Shineion//Desktop//爬蟲圖"
dir = "C://Users//Shineion//Desktop//爬蟲圖//" + keyword
if os.path.exists(last_dir):
if os.path.exists(dir):
print("檔案夾已經存在")
else:
os.mkdir(dir)
print(dir + "已經創建成功")
else:
os.mkdir(last_dir)
if os.path.exists(dir):
print("檔案夾已經存在")
else:
os.mkdir(dir)
print(dir + "已經創建成功")
keyword1 = quote(keyword, encoding="utf-8")
url = 'http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + keyword1 + '&ct=201326592&v=flip'
req = urllib.request.Request(url, headers=headers)
f = urllib.request.urlopen(req).read().decode("utf-8")
key = r'thumbURL":"(.+?)"'
key1 = re.compile(key)
num = 0
for string in re.findall(key1, f):
print("正在下載" + string)
f_req = urllib.request.Request(string, headers=headers)
f_url = urllib.request.urlopen(f_req).read()
fs = open(dir + "/" + keyword + str(num) + ".jpg", "wb+")
fs.write(f_url)
fs.close()
num += 1
print(string + "已下載成功")
input("按任意鍵結束程式:")
注意問題:代碼容易卡住,在獲取某一圖片時卡住

作者:電氣-余登武
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/250224.html
標籤:python
上一篇:猜生日號數
