記事ディレクトリ
1.原則
Web ページ内の画像には独自の URL があり、その URL にアクセスすることで直接画像を取得できます。たとえば、次の URL にアクセスすると、画像を取得できます。
https://img-blog.csdnimg.cn/a3bad4725ba94301b7cba7dd8209fea4.png#pic_center
したがって、画像を一括クロールする処理は、URL を一括して取得する処理となります。
2. バッチ画像 URL の保存アドレスを見つける
- 画像 URL を一括で取得する方法は Web サイトごとに若干異なりますが、ここでは Bing を例に説明します。
2.1 百度
- 画像検索のために Baidu を開いて、F12 を押して開発者モードを開きます
- その他のツールの「ネットワーク」を開きます
- このタイプのリクエストを見つける
- 対応する説明は図に示すとおりです
- 実際、このタイプのリクエストには、Baidu 画像の URL 情報が保存されています。このようなリクエストの完全な URL は次のとおりです。
https://image.baidu.com/search/acjson?tn=resultjson_com&logid=9612443976471669297&ipn=rj&ct=201326592&is=&fp=result&fr=&word=%E5%B7%A5%E7%A8%8B%E5%B8%88&queryWord=%E5%B7%A5%E7%A8%8B%E5%B8%88&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=©right=&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&expermode=&nojc=&isAsync=&pn=30&rn=30&gsm=1e&1681996706325=
- pnパラメータは表示される画像の数を決定し、30 の倍数です。
- queryWordパラメータとwordパラメータは検索キーワードです
- この URL にアクセスすると、次のような厄介な情報が表示されます。
- この情報が適切に処理されていれば、すべての画像の URL を抽出できます。
2.2 総合
- Sogou と Baidu は、次のように、画像 URL を保存するために異なるリクエスト ヘッダー名を使用します。
2.3 ビング
Bing が画像 URL を保存するために使用する要求ヘッダーは次のとおりです。
2.4 概要
- Webサイトの画像URLを一括保存しているリクエストヘッダーがあれば、このリクエストヘッダーにアクセスすることでテキストデータを取得できます。次にBingを例に、乱雑な情報から画像URLを一括抽出する方法を説明します。
3. 画像の URL を格納するリクエスト ヘッダーを処理する
- 上で述べたように、このタイプのリクエスト ヘッダーの情報は非常に複雑です。ただし、図に示すように、正規化を使用して画像の URL を除外できます。
- ご覧のとおり、この正規表現により、すべての画像の URL が抽出されます。
4. 完全なデモ
画像 URL のバッチを使用すると、ダウンロードは簡単です。urlretrieve 関数を使用して、リモート データをローカルに直接ダウンロードします。詳細については、以下の完全なデモをご覧ください。
# Created by Han Xu
# email:[email protected]
import requests
import urllib.request
import urllib.parse
import os
import re
class Spider_bing_image():
def __init__(self):
"""
@:brief
@:return
"""
self.path=input("type in the path where you want to reserve the images:")
self.url = 'https://www4.bing.com/images/async?'
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.48'}
self.keyword = input("type in the keywords used to search in bing:")
self.paginator = int(input("Type in the number of pages you want.Each page has almost 30 images:"))
def get_urls(self):
"""
@:brief Get the URLs that you need to visit.
@:return return a list of the URLs
"""
keyword = urllib.parse.quote(self.keyword)
params = []
for i in range(1, self.paginator + 1):
params.append(
"q={}&first={}&count=35&cw=1233&ch=946&relp=35&datsrc=I&layout=RowBased_Landscape&apc=0&mmasync=1&dgState=x*303_y*1355_h*185_c*1_i*36_r*8&IG=6A228D01DCE044E685557DE143D55D91&SFX=2&iid=images.5554".format(
keyword,30 * i))
urls = []
for i in params:
urls.append(self.url + i)
return urls
def get_path(self):
"""
@:brief Get the path where you want to reserve the images.
@:return
"""
dirname="./"+self.path
dirname_origin = dirname
int_index = 0
while(True):
IsExist = os.path.exists(dirname)
if (IsExist==False):
os.mkdir(dirname)
IsCreate=True
break
else:
int_index+=1
dirname=dirname_origin+"({})".format(int_index)
return dirname+"/"
def get_image_url(self, urls):
"""
@:brief Get the URLs of images.
@:return a list of URLs of images
"""
image_url = []
pattern_string="http[^%&]+.jpg"
pattern = re.compile(pattern=pattern_string)
for url in urls:
url_txt = requests.get(url, headers=self.headers).text
url_list=pattern.findall(url_txt)
for i in url_list:
if i:
image_url.append(i)
return image_url
def get_image(self,image_url):
"""
@:brief download the images into the path you set just
@:return
"""
m = 1
for img_url in image_url:
#定义一个flag用于判断下载图片是否异常
flag=True
try:
#urlretrieve() 方法直接将远程数据下载到本地
print("第{}张图片的URL是{}".format(m,img_url))
print("保存于{}".format(os.getcwd()+self.path[1:]))
urllib.request.urlretrieve(img_url, self.path + str(m) + '.jpg')
except BaseException as error:
flag=False
print(error)
if(flag):
#下载完成提示
print('**********第'+str(m)+'张图片下载完成********')
#每下载完后一张,m累加一次
m = m + 1
print('下载完成!')
return
def __call__(self, *args, **kwargs):
"""
@brief the constrcution of the class
@:return
"""
self.path=self.get_path()
urls = self.get_urls()
image_url = self.get_image_url(urls)
self.get_image(image_url)
return