1.この記事を書いた理由
私は長い間クローラーを書いておらず、ほとんど忘れていました。ステーションpのクロール画像から始めて、クローラーを確認して練習します。
2. Webページのソースコードを取得する
Webページデータをクロールするプロセスは、主に要求ライブラリを使用します。簡単なWebクローラーの実装プロセスは、次のステップに大別できます。
- クロールURLを指定してください
- クロールリクエストを開始する
- クロールデータの保存
pixiv Webサイトのクロールを例にとり、pixiv Webサイトのホームページのソースコードを取得してpixiv1.htmlファイルに保存します。
import requests
if __name__ == "__main__":
# step 1: 爬取网页数据
# 指定url
url = 'https://www.pixiv.net/'
# 发起请求
home_text = requests.get(url).text
# step 2: 解析爬取数据
# step 3: 存储爬取数据
save_path = './pixiv1.html'
with open(save_path, 'w', encoding='utf-8') as fp:
fp.write(home_text)
print('下载成功!')
上記の操作後、現在のディレクトリに「pixiv1.html」ファイルが生成されます。ファイルをダブルクリックして開くと、下の画像のようになっていることがわかります。最初にWebサイトにアクセスするにはログインする必要があるため、ログイン登録ページにジャンプします。ページはすべて日本語です。
この問題を解決するには、右クリックしてWebページを確認し、ネットワークに入り、ページを更新します。データの更新がある場合は、クリックしてヘッダーを表示します。リクエストヘッダーにCookieがあることが判明したため、UAを偽装し、リクエストヘッダーを設定し、リクエストヘッダーをコードブロックにコピーする必要があります。
# 指定url
url = 'https://www.pixiv.net/'
headers = {
'user-agent': '你的user-agent',
'referer':'https://www.pixiv.net/',
'sec-fetch-dest':'document',
'sec-fetch-mode':'navigate',
'sec-fetch-site':'same-origin',
'sec-fetch-user':'1',
'upgrade-insecure-requests':'1',
'accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-encoding':'gzip, deflate, br',
'accept-language':'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'cache-control':'max-age=0',
'cookie': '你的浏览器cookie'
}
# 发起请求
home_text = requests.get(url, headers=headers).text
保存したWebページファイル「pixiv2.html」を再度開き、下の図に示すように、ログインしたページとは異なるページであることを確認します。
キッズ、あなたはたくさんの疑問符を持っていますか...
3、1つのサムネイルをクロールする
前の章からわかるように、ホームページのイラスト部分はホームページの直接のソースコードではなく、別のWebページアドレスとスクリプトを紹介しています。ここでは、Webページを入力して分析し、画像を右クリックして[チェック]をクリックし、画像アドレスを取得します。画像は比較的小さく、サムネイルです。画像のアドレスをコピーして、ブラウザのアドレスバーに貼り付け、画像を表示します。
取得した画像のアドレスに従って、画像アドレスに直接アクセスし、画像データを取得してローカルに保存します。
import requests
if __name__ == "__main__":
# 指定url
url = 'https://i.pximg.net/c/360x360_70/custom-thumb/img/2020/09/19/02/56/19/84460298_p0_custom1200.jpg'
# 发起请求
img_data = requests.get(url).content
# 存储图片
img_path = './1.jpg'
with open(img_path, 'wb') as fp:
fp.write(img_data)
print('下载成功!')
したがって、「1.jpg」という名前の画像が現在のディレクトリに生成されます。ダブルクリックして開き、エラーを見つけます。以下に示すように。
これは、リクエストヘッダー情報が欠落しており、リクエストヘッダーを追加する必要があるためです。コードは次のとおりです。
# 指定url
url = 'https://i.pximg.net/c/360x360_70/custom-thumb/img/2020/09/19/02/56/19/84460298_p0_custom1200.jpg'
# UA伪装
headers = {
'user-agent': '你的user-agent',
'cookie': '你的浏览器cookie',
'referer':'https://www.pixiv.net/',
'sec-fetch-dest':'document',
'sec-fetch-mode':'navigate',
'sec-fetch-site':'same-origin',
'sec-fetch-user':'1',
'upgrade-insecure-requests':'1',
'accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-encoding':'gzip, deflate, br',
'accept-language':'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'cache-control':'max-age=0',
}
# 发起请求
img_data = requests.get(url, headers=headers).content
「1.jpg」ファイルが生成され、ダブルクリックして開くと、1つの画像が正常にクロールされます。
3.単一の高解像度の元の画像をクロールする
1.元の画像アドレスを取得する
元の画像をクロールするには、最初に画像アドレスを取得する必要があります。次の図に示すように、イラストのサムネイルをクリックしてイラストの詳細ページに入り、イラスト画像の検査Webページを右クリックします。
左側の画像をクリックして大きな画像のプレビューモードに入り、検査Webページを右クリックすると、右側の赤いボックス内のラベルのリンクアドレスが、図の元の画像アドレスであることがわかります。しかし、アドレスをブラウザのアドレスバーにコピーすると、403ステータスコードが表示されます。このとき、クリックして元のWebページに戻り、画像をクリックして大きな画像モードに入り、ブラウザのアドレスバーにアドレスをコピーして画像を表示すると、画像が正常に表示されていることがわかります。
2. HDオリジナル画像をクロールする
import requests
if __name__ == "__main__":
# step 1: 指定url
url = 'https://i.pximg.net/img-original/img/2020/09/19/02/56/19/84460298_p0.jpg'
headers = {
'referer': 'https://www.pixiv.net/artworks/84460298',
'user-agent':'你的user-agent'
}
# step 2:发起请求
res_data = requests.get(url, headers = headers)
# step 3: 存储数据
res_code = res_data.status_code
msg = '下载成功!'
if res_code == 200 : # 请求成功
img_data = res_data.content
# 存储数据
img_path = './img/5.png'
with open(img_path, 'wb') as fp:
fp.write(img_data)
print(msg)
else: # 请求失败
msg = "下载失败,返回状态码为:"+str(res_code)
print(msg)
上記で取得した元の画像アドレスに従って、元の画像を要求するプロセスでヘッダーのリファラーパラメーターを設定する必要があります。そうしないと、要求は成功しません。
リクエストは失敗した場合があり、返却されたステータスコードにより判断できます。ステータスが200の場合はokでリクエストが成功したことを意味し、それ以外の場合はリクエストが失敗したことを意味し、ステータスコード情報が出力されます。
4番目に、高解像度の元の画像をバッチクロールします。
「手動で右クリックして名前を付けて保存」と比較すると、上記の単一の画像のクロールは本当に時間と手間がかかり、クローラーの利点を反映していないだけでありません。扱いにくい機械では、クローラーを使用すると、この操作を簡単かつ迅速に実行できます。
1.元の画像アドレスを分析する
前のセクションからわかるように、ここでは画像アドレスを直接表示して、複数の画像を取得します。複数の画像を取得する方法の1つは、すべての画像アドレスを記録してファイルに保存し、ファイル内の画像アドレスを読み取って画像をダウンロードする方法です。もう1つの方法は、画像アドレスのロジック、構成、および関係を分析する方法です。明らかに後者はより科学的で便利です。複数の画像を右クリックして、次の画像アドレスを取得します。
- https://i.pximg.net/img-original/img/2020/09/20/19/00/02/84495797_p0.jpg
- https://i.pximg.net/img-original/img/2020/09/19/18/00/29/84470884_p0.jpg
- https://i.pximg.net/img-original/img/2020/09/20/06/17/10/84484828_p0.png
- https://i.pximg.net/img-original/img/2020/09/19/00/00/44/84457006_p0.jpg
最初の写真のアドレスを例にとると、アドレスの前の「https://i.pximg.net/img-original/img/」と後ろの「_p0.jpg」はパブリック部分であり、中央部分のみであることがわかります2020 / 09/19/18/00/29/84470884「住所は他の写真とは異なります。
ネットワークでXHRプレビューを表示して各xhrメッセージの件名を確認し、次の画像コンテンツを取得します。
上の図のjsonデータには、元の画像アドレスとリファラーの形成に参加する最後のキーなど、さまざまな画像情報が含まれており、内部のURLのコンテンツは、元の画像のサムネイルアドレスであり、元の画像の特別な部分に関する情報があります。したがって、元の画像のURLは、jsonデータを解析することによって構築できます。
2.元の画像アドレスを作成する
最初にプレビューに対応するxhr情報を見つけ、次にリクエストURLをコピーしてアクセスをリクエストします。コーディングは次のように実装されます:
import requests
import json
import pprint
if __name__ == "__main__":
# step 1: 指定url
url = 'https://www.pixiv.net/ajax/user/10797546/illusts?ids%5B%5D=84243244&ids%5B%5D=84089827&ids%5B%5D=83931617&ids%5B%5D=83817260&ids%5B%5D=83774711&ids%5B%5D=83630300&ids%5B%5D=83447790&ids%5B%5D=83294064&ids%5B%5D=83293792&ids%5B%5D=82883638&ids%5B%5D=82210044&ids%5B%5D=81883995&ids%5B%5D=81415445&ids%5B%5D=80789668&ids%5B%5D=79598338&ids%5B%5D=79218284&ids%5B%5D=78917052&ids%5B%5D=78768898&ids%5B%5D=78711808&lang=zh'
headers = {
'accept':'application/json',
'accept-encoding':'gzip, deflate, br',
'accept-language':'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'cookie':'你的cookie',
'referer': 'https://www.pixiv.net/artworks/84460298',
'sec-fetch-dest':'empty',
'sec-fetch-mode':'cors',
'sec-fetch-site':'same-origin',
'user-agent':'你的user-agent',
}
# step 2:发起请求
res_data = requests.get(url, headers = headers)
# step 3: 查看请求结果
res_json = res_data.json()
pprint.pprint(res_json)
リクエストURLはjsonデータに対応するインターフェースアドレスであり、アドレスにアクセスすることで、画像情報を含む必要なjsonデータが返されることがわかります。
表示されたjsonデータによれば、複数の画像情報が含まれていることがわかり、要求結果を解析することで複数の画像アドレスを構築できます。リクエスト結果で返されるデータは辞書型のデータで、本文の内容はとても便利です。最初に、おそらく結果データの本体部分、そして次にlistメソッドを通じて、ディクショナリのすべてのキー、つまり画像のIDを取得できます。origin_url_listとorigin_title_listの2つの配列をそれぞれ定義することにより、すべての元のイメージアドレスと元のイメージ名が保存されます。値を直接取得してリストに追加することで画像のタイトルを取得し、正規表現を通じてサムネイルのアドレスを解析して元の画像の特別な部分を取得し、文字列スプライシングを実行して元の画像のアドレスを取得します。最後に、作成したデータが正しいかどうかを印刷して確認できます。
# step 3: 解析json数据
res_json = json_res_data.json()
res_json_body = res_json['body'] # 获取json中的body内容
id_list = list(res_json_body) # 获取body中的所有的key,即图片id
origin_url_list = [] # 保存所有的原图地址
origin_title_list = []
# step 4: 构造原图地址
for item in id_list:
# 获取title
origin_title_list.append(res_json_body[item]['title'])
# 通过获取缩略图地址构造原图地址
thumbnail_url = res_json_body[item]['url']
origin_specail_part = re.findall('img/(.*?)_p0',thumbnail_url)[0]
origin_url_list.append("https://i.pximg.net/img-original/img/%s_p0.jpg" % origin_specail_part)
# step 4: 打印查看结果是否正确
i = -1
for item in origin_url_list:
# 更新索引
print(origin_title_list[i])
print(id_list)
print(item)
print()
3.元の画像をバッチでクロールする
上記の手順の後、画像のリファラーパラメーターに含まれるURL、タイトル、画像IDなどの情報を取得し、この情報に基づいてアクセス要求を開始して、画像をローカルに保存できます。この時点で、画像のバッチクロールは成功しています。
import requests
import pprint
import json
import re
if __name__ == "__main__":
# step 1: 指定url
json_url = 'https://www.pixiv.net/ajax/user/10797546/illusts?ids%5B%5D=84243244&ids%5B%5D=84089827&ids%5B%5D=83931617&ids%5B%5D=83817260&ids%5B%5D=83774711&ids%5B%5D=83630300&ids%5B%5D=83447790&ids%5B%5D=83294064&ids%5B%5D=83293792&ids%5B%5D=82883638&ids%5B%5D=82210044&ids%5B%5D=81883995&ids%5B%5D=81415445&ids%5B%5D=80789668&ids%5B%5D=79598338&ids%5B%5D=79218284&ids%5B%5D=78917052&ids%5B%5D=78768898&ids%5B%5D=78711808&lang=zh'
json_url_headers = {
'accept':'application/json',
'accept-encoding':'gzip, deflate, br',
'accept-language':'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'cookie':'你的cookie',
'referer': 'https://www.pixiv.net/artworks/84460298',
'sec-fetch-dest':'empty',
'sec-fetch-mode':'cors',
'sec-fetch-site':'same-origin',
'user-agent':'你的user-agent',
'x-user-id':'你的user-id',
}
# step 2:发起请求
json_res_data = requests.get(json_url, headers = json_url_headers)
# step 3: 解析json数据
res_json = json_res_data.json()
res_json_body = res_json['body'] # 获取json中的body内容
id_list = list(res_json_body) # 获取body中的所有的key,即图片id
origin_url_list = [] # 保存所有的原图地址
origin_title_list = []
# step 4: 构造原图地址
for item in id_list:
# 获取title
origin_title_list.append(res_json_body[item]['title'])
# 通过获取缩略图地址构造原图地址
thumbnail_url = res_json_body[item]['url']
origin_specail_part = re.findall('img/(.*?)_p0',thumbnail_url)[0]
origin_url_list.append("https://i.pximg.net/img-original/img/%s_p0.jpg" % origin_specail_part)
# step 4: 遍历origin_url_list爬取图片
i = -1
for item in origin_url_list:
# 更新id列表索引
i = i+1
# 获取地址
origin_url = item
# 设置headers
origin_url_headers = {
'referer': 'https://www.pixiv.net/artworks/%s' % str(id_list[i]),
'user-agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36'
}
# 发起请求
img_res = requests.get(origin_url, headers=origin_url_headers)
img_res_data = img_res.content
img_res_code = img_res.status_code
if img_res_code == 200: # 如果请求成功
# 存储图片
img_save_name = str(origin_title_list[i])+".png"
with open("./img/"+img_save_name, 'wb') as fp:
fp.write(img_res_data)
msg = img_save_name+"保存成功!"
print(msg)
else: # 否则输出状态码
msg = "下载失败!状态码为:"+ img_res_code
print(msg)
保存結果は以下のとおりです。
最後に書かれた:
1.この記事の画像のクロールは、長い間ブロガーの指導の下で完了しており、ブログのPステーションのクローラーを参照すると、元の画像pngは分析プロセス中にバッチでクロールされました。
2.読者が役に立ったと思ったら、ブロガーが気に入ってくれて嬉しいので、下の小指を光らせてください。