基于360搜图爬取图片
利用360搜圖爬取圖片
? 最近閑得無聊,搞了個基于360搜圖的圖片爬取。用得都是比較基礎的知識,所以這里也分享一下代碼。本人也不是什么大佬。代碼看看就行。**完整的代碼在文章最后面。**下面我就簡單介紹一下我爬取的過程。
1.第一步
首先我們要知道360關鍵字是用什么鍵來對應的,我記得360是q對應關鍵字,百度的是wd對應關鍵字。
如下360連接https://image.so.com/i?q=%E9%A3%9E%E6%9C%BA&src=srp,這里的q后面的%E9%A3%9E%E6%9C%BA就是對應的url編碼,知道了連接之后,我們就可以打開網頁。
打開網頁的代碼如下:
# 打開url返回沒有解碼的html def open_url(url):r.Request(url).add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36')respond = r.urlopen(url)try:if respond.getcode() == 200:html = respond.read()except Exception as e:page = e.partialhtml = pagereturn html注意的是:我這里沒有對爬回來的HTML代碼進行encode,也就是說這里的html是二進制的。要解碼就需要.encode(‘utf-8’)。
2.第二步
第二步就是分析網頁結構了。看看圖片都藏在哪里,通過瀏覽器F12,我們可以看到源代碼,我找到了圖片的地方。
從這里我們可以找到圖片是所在位置,并且我們可以找到圖片的下載地址,但問題來了,這個頁面是動態的,也就是說圖片的獲取也是動態的啦,如果我們只是通過定位到圖片,在找圖片的地址,未免有點笨了。
然后我繼續查看網絡傳送那里和頁面代碼,然后我在頁面那里找到了頁面圖片初始化的數據。這些數據存在一段js代碼里面,并且數據的結構是json。
這里我寫了兩函數來獲取信息,我沒有使用正則表達式,只是單純的做了個定位。
# 這里只是針對初始化數據(頁面前60-100張進行爬取) def json_FindInitimg(string, imgurl_dict):js = json.loads(string) # 將標簽中的信息進行json加載for elevent in iter(js):if type(js[elevent]) == type([]):for lis in js[elevent]:for (key, value) in lis.items():if key == 'thumb_bak':imgurl_dict[value] = value.split('/')[-1].split('.')[-1]return imgurl_dict# 獲取初始化的圖片(一般是頁面前60或100張) def find_imgurl(html):if html == None:returnimgurl_dict = {}d = pq(html) # 用爬回來的網頁str進行網頁分析scr = d('body')('script')('#initData') # 找到對應的標簽imgurl_dict = json_FindInitimg(scr.html(), imgurl_dict)return imgurl_dict爬取的圖片連接:(這里要的是下載連接,當然也可以要圖片原網站地址)
生成的字典格式,key是地址,val是圖片格式
當然這些是不夠的,這些都是頁面初始化的數據。我要的是那些動態傳送過來的圖片,果然我找到了圖片數據的請求。
并且那些需要的參數我也找到了。它放在一個js代碼段里面。這里的sid等其他參數,每次打開網頁都不同。
現在就是萬事俱備,只欠東風。
首先拿到那些需要的參數
def find_param(html):if html == None:returnd = pq(html) # 用爬回來的網頁str進行網頁分析scr = d('body')('script')('#initParam') # 找到對應的標簽param_dict = json.loads(scr.html().replace("'", '"')) #爬取回來的參數字典return param_dict然后:(形成連接的url)
# 通過參數形成新的url(通過這些參數形成新的url) def Newurl(param_dict, num=1):urllist = []sn = 60ps = 1for i in range(num):URLdata = {'q': p.unquote(param_dict['query']),'pd': 1,'pn': 60,'correct': p.unquote(param_dict['query']),'adstar': param_dict['adstar'],'tab': param_dict['tab'],'sid': param_dict['sid'],'ras': param_dict['ras'],'cn': param_dict['cn'],'gn': param_dict['gn'],'kn': param_dict['kn'],'crn': param_dict['crn'],'bxn': param_dict['bxn'],'cuben': param_dict['cuben'],'src': 'srp','sn': sn,'ps': ps,'pc': 60}url = 'https://image.so.com/j?' + p.urlencode(URLdata)print('生成批道url: ' + url)urllist.append(url)sn += 70ps += 70return urllist3.第三步
下載圖片下載圖片就非常簡單了,直接打開圖片連接,然后把打開的連接中讀取二進制數據,然后保存到文件里面,加上對應的文件命和后綴。
代碼在后面。
4.完整代碼
我也不多說,放在也是爬來玩玩,直接給代碼。能力水平和精力有限,代碼可能有點粗糙。如果出現什么BUG還請各位自己修改。最后說一下,代碼里面有兩個爬取方向,一個是頁面是初始化圖片,一個是基于參數請求新的圖片。
import urllib.request as r import urllib.parse as p from pyquery import PyQuery as pq import json import os# 打開url返回沒有解碼的html def open_url(url):r.Request(url).add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36')respond = r.urlopen(url)try:if respond.getcode() == 200:html = respond.read()except Exception as e:page = e.partialhtml = pagereturn html# 獲取初始化的圖片(一般是頁面前60或100張) def find_imgurl(html):if html == None:returnimgurl_dict = {}d = pq(html) # 用爬回來的網頁str進行網頁分析scr = d('body')('script')('#initData') # 找到對應的標簽imgurl_dict = json_FindInitimg(scr.html(), imgurl_dict)return imgurl_dict# 獲取請求參數(獲取請求參數) def find_param(html):if html == None:returnd = pq(html) # 用爬回來的網頁str進行網頁分析scr = d('body')('script')('#initParam') # 找到對應的標簽param_dict = json.loads(scr.html().replace("'", '"')) #爬取回來的參數字典return param_dict# 通過參數形成新的url(通過這些參數形成新的url) def Newurl(param_dict, num=1):urllist = []sn = 60ps = 1for i in range(num):URLdata = {'q': p.unquote(param_dict['query']),'pd': 1,'pn': 60,'correct': p.unquote(param_dict['query']),'adstar': param_dict['adstar'],'tab': param_dict['tab'],'sid': param_dict['sid'],'ras': param_dict['ras'],'cn': param_dict['cn'],'gn': param_dict['gn'],'kn': param_dict['kn'],'crn': param_dict['crn'],'bxn': param_dict['bxn'],'cuben': param_dict['cuben'],'src': 'srp','sn': sn,'ps': ps,'pc': 60}url = 'https://image.so.com/j?' + p.urlencode(URLdata)print('生成批道url: ' + url)urllist.append(url)sn += 70ps += 70return urllist# 這里只是針對(頁面前60-100張進行爬取) def json_FindInitimg(string, imgurl_dict):js = json.loads(string) # 將標簽中的信息進行json加載for elevent in iter(js):if type(js[elevent]) == type([]):for lis in js[elevent]:for (key, value) in lis.items():if key == 'thumb_bak':print((key, value))imgurl_dict[value] = value.split('/')[-1].split('.')[-1]return imgurl_dict# 下載 def download(dirpath, imgurl_dict):count = 0print(imgurl_dict)for (imgurl, type) in imgurl_dict.items():if type == 'jpg' or type == 'png' or type == 'jpeg':print("圖片[ %s ]開始下載......" % imgurl)html = open_url(imgurl)path = dirpath + str(count) + '.' + typeprint("圖片寫入路徑是:%s" % dirpath + path)with open(path, mode='wb') as f:f.write(html)count += 1return count# 不同的下載方式,下載不同數量的圖片 def download_img(url, dirpath, num=None):Pcount = 1 # 批道數if num == None:html = open_url(url).decode('utf-8')imgurl_dict = find_imgurl(html)os.mkdir(dirpath + str(Pcount))download(dirpath+str(Pcount)+'\\', imgurl_dict)else:html = open_url(url).decode('utf-8')for i in Newurl(find_param(html), num=num):newhtml = open_url(i).decode('utf-8')imgurl_dict = {}json_FindInitimg(newhtml, imgurl_dict)os.mkdir(dirpath+str(Pcount)) #工具批道數新建文件夾download(dirpath+str(Pcount)+'\\', imgurl_dict) #下載到對應的文件夾Pcount +=1if __name__ == '__main__':path = 'F:\\my_img\\' #根目錄(每一批會在根目錄建一個新目錄) 最后記得加個'\\'結尾Qval = input('請輸入你要搜索的圖片:')mod = input('請輸入爬取方式:(1:爬取頁面前60-100張\t0:爬取指定數量)')data = {'q': Qval,'src': 'srp'}url = 'https://image.so.com/i?' + p.urlencode(data)if mod == '1':download_img(url, dirpath=path)else:num = int(input('請輸入爬取批數:(一般60/批)'))download_img(url, dirpath=path, num=num)爬取結果如下:(爬取的一些動漫圖片)
總結
以上是生活随笔為你收集整理的基于360搜图爬取图片的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 特斯拉 Model 3 网约车不堪高强度
- 下一篇: 华为新专利可保护 AI 大模型版权,自动