史上最も完成度の高い!Python クローラーリクエストライブラリ (ケース付き)

1.リクエストライブラリの紹介

Requests は、人間向けに設計されたシンプルでエレガントな HTTP ライブラリです。リクエスト ライブラリはネイティブ HTTP ライブラリであり、urllib3 ライブラリよりも使いやすいです。リクエスト ライブラリは、クエリ文字列を URL に手動で追加したり、POST データをフォーム エンコーディングしたりせずに、ネイティブ HTTP 1.1 リクエストを送信します。urllib3 ライブラリと比較して、request ライブラリには完全に自動化されたキープアライブ機能と HTTP 接続プール機能があります。リクエスト ライブラリには次の機能が含まれています。

❖ 1キープアライブと接続プール

❖ 国際化されたドメイン名と URL

❖ 永続的な Cookie を使用したセッション

❖ ブラウザベースのSSL認証

❖ コンテンツの自動デコード

❖ 基本認証/ダイジェスト認証

❖ エレガントなキー/値 Cookie

❖ 自動解凍

❖ Unicode レスポンスボディ

❖ HTTP(S) プロキシのサポート

❖ ファイルを分割してアップロードする

❖ ストリーミングダウンロード

❖ 接続がタイムアウトしました

❖ チャンク化されたリクエスト

❖ .netrcのサポート

1.1 リクエストのインストール

pip install requests

1.2 リクエストの基本的な使い方

コード リスト 1-1: get リクエストを送信し、返された結果を表示する

import requests
url = 'http://www.tipdm.com/tipdm/index.html' # 生成get请求
rqg = requests.get(url)
# 查看结果类型
print('查看结果类型:', type(rqg))
# 查看状态码
print('状态码:',rqg.status_code)
# 查看编码
print('编码 :',rqg.encoding)
# 查看响应头
print('响应头:',rqg.headers)
# 打印查看网页内容
print('查看网页内容:',rqg.text)
查看结果类型:<class ’requests.models.Response’>
状态码:200
编码 :ISO-8859-1
响应头:{’Date’: ’Mon, 18 Nov 2019 04:45:49 GMT’, ’Server’: ’Apache-Coyote/1.1’, ’
Accept-Ranges’: ’bytes’, ’ETag’: ’W/"15693-1562553126764"’, ’Last-Modified’: ’
Mon, 08 Jul 2019 02:32:06 GMT’, ’Content-Type’: ’text/html’, ’Content-Length’: ’
15693’, ’Keep-Alive’: ’timeout=5, max=100’, ’Connection’: ’Keep-Alive’}

1.3 リクエストの基本的なリクエスト方法

すべての http リクエストはリクエスト ライブラリを通じて送信できます。

requests.get("http://httpbin.org/get") #GET请求
requests.post("http://httpbin.org/post") #POST请求
requests.put("http://httpbin.org/put") #PUT请求
requests.delete("http://httpbin.org/delete") #DELETE请求
requests.head("http://httpbin.org/get") #HEAD请求
requests.options("http://httpbin.org/get") #OPTIONS请求

2. Request を使用して GET リクエストを送信します

HTTP で最も一般的なリクエストの 1 つは GET リクエストです。リクエストを使用して GET リクエストを作成する方法を詳しく見てみましょう。

GET パラメータの説明: get(url, params=None, **kwargs):

❖ URL: リクエストする URL

❖ params : (オプション) 辞書、リクエストのクエリ文字列に対して送信されたタプルまたはバイトのリスト

❖ **kwargs: 可変長のキーワード引数

まず、最も単純な GET リクエストを作成します。リクエストのリンクは http://httpbin.org/get です。Web サイトは、クライアントが GET リクエストを開始すると、対応するリクエスト情報を返すと判断します。次のように使用します。 GET リクエストを構築するためのリクエスト

import requests
r = requests.get(http://httpbin.org/get)
print(r.text)
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-5fb5b166-571d31047bda880d1ec6c311"
},
"origin": "36.44.144.134",
"url": "http://httpbin.org/get"
}

GET リクエストが正常に開始され、返された結果にはリクエスト ヘッダー、URL、IP などの情報が含まれていることがわかります。では、GET リクエストで追加情報を添付したい場合、一般的にはどのように追加するのでしょうか?

2.1 ヘッダー付きのリクエストを送信する

まず、Zhihu のホームページ情報をリクエストしてみます。

import requests
response = requests.get(’https://www.zhihu.com/explore’)
print(f"当前请求的响应状态码为:{response.status_code}")
print(response.text)

現在のリクエストの応答ステータス コードは次のとおりです: 400

400不正な要求


オープンレスティ

ここでは、応答のステータス コードが 400 であることがわかり、リクエストが失敗したことを示しています。Zhihu が私たちがクローラーであることを発見したため、ブラウザを偽装し、対応する UA 情報を追加する必要があります。

import requests
headers = {"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’}
response = requests.get(’https://www.zhihu.com/explore’, headers=headers)
print(f"当前请求的响应状态码为:{response.status_code}")
# print(response.text)

現在のリクエストの応答ステータス コードは次のとおりです: 200

<!doctype html>

……

ここでは、ブラウザの識別情報である User-Agent フィールド情報を含むヘッダー情報を追加します。どうやら私たちの変装は成功したようです!ブラウザを装うこの方法は、最も簡単なクロール対策の 1 つです。

GETパラメータの説明: リクエストヘッダを付けてリクエストを送信する方法

request.get(url, headers=ヘッダー)

-headers パラメータは、辞書の形式でリクエスト ヘッダーを受け取ります。

・リクエストヘッダのフィールド名をキーとし、フィールドに対応する値を値として使用します。

練習

Baidu のホームページ https://www.baidu.com をリクエストし、ヘッダーの送信をリクエストし、リクエストされたヘッダー情報を印刷します。

ほどく

import requests
url = 'https://www.baidu.com'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
# 在请求头中带上User-Agent,模拟浏览器发送请求
response = requests.get(url, headers=headers)
print(response.content)
# 打印请求头信息
print(response.request.headers)

2.2 パラメータを指定してリクエストを送信する

Baidu 検索を使用すると、URL アドレスに「?」が含まれることがよくあります。その場合、疑問符はリクエスト パラメータであり、クエリ文字列とも呼ばれます。

通常、私たちは基本的な Web ページにアクセスするだけではなく、特に動的な Web ページをクロールする場合、異なるコンテンツを取得するには異なるパラメーターを渡す必要があります。GET にはパラメーターを渡すための 2 つのメソッドがあり、リンクにパラメーターを直接追加するか、パラメーターを使用して追加することができます。パラメーター。

2.2.1 URL でパラメータを運ぶ

パラメータを使用して URL に対して直接リクエストを開始します。

import requests
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
url = ’https://www.baidu.com/s?wd=python’
response = requests.get(url, headers=headers)

2.2.2 params を介してパラメータ辞書を運ぶ

1. リクエストパラメータの辞書を構築する

2. インターフェイスにリクエストを送信するときにパラメータ ディクショナリを取得し、パラメータ ディクショナリを params に設定します。

import requests
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
# 这是目标url
# url = ’https://www.baidu.com/s?wd=python’
# 最后有没有问号结果都一样
url = ’https://www.baidu.com/s?’
# 请求参数是一个字典 即wd=python
kw = {’wd’: ’python’}
# 带上请求参数发起请求,获取响应
response = requests.get(url, headers=headers, params=kw)
print(response.content)

実行結果から判断すると、要求されたリンクは次のように自動的に構築されます。

http://httpbin.org/get?key2=value2&key1=value1 。

また、Web ページの戻り値の型は実際には str 型ですが、非常に特殊であり、JSON 形式になっています。したがって、返された結果を直接解析して辞書形式を取得したい場合は、 json() メソッドを直接呼び出すことができます。例は次のとおりです。

import requests
r = requests.get("http://httpbin.org/get")
print( type(r.text))
print(r.json())
print( type(r. json()))

< クラス 'str' >

{ 'args' : {}, 'headers' : { 'Accept' : '*/*' , 'Accept-Encoding' : 'gzip, deflate' , 'Host'

'httpbin.org' 、 'ユーザーエージェント' : 'python-requests/2.24.0' 、 'X-Amzn-Trace-Id' : '

ルート=1-5fb5b3f9-13f7c2192936ec541bf97841' }, 'origin' : '36.44.144.134' , 'url' : '

http://httpbin.org/get' }

< クラス 'dict' >

json() メソッドを呼び出すことで、返された JSON 形式の文字列を辞書に変換できることがわかります。ただし、返された結果が JSON 形式でない場合、解析エラーが発生し、 json.decoder.JSONDecodeError 例外がスローされることに注意してください。

補足コンテンツとして、受信した辞書文字列は次のように自動的にエンコードされて URL に送信されます。

import requests
headers = {’User-Agent’: ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36’}
wd = ’张三同学’
pn = 1
response = requests.get(’https://www.baidu.com/s’, params={’wd’: wd, ’pn’: pn},
headers=headers)
print(response.url)

# 出力は次のとおりです: https://www.baidu.com/s?wd=%E9%9B%A8%E9%9C%93%E5%90%8

C%E5%AD%A6&pn=1

# URLが自動的にエンコードされていることがわかります

上記のコードは次のコードと同等です。params エンコード変換は基本的に urlencode を使用します。

import requests
from urllib.parse import urlencode
headers = {’User-Agent’: ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko)
wd = ’张三同学’
encode_res = urlencode({’k’: wd}, encoding=’utf-8’)
keyword = encode_res.split(’=’)[1]
print(keyword)
# 然后拼接成url
url = ’https://www.baidu.com/s?wd=%s&pn=1’ % keyword
response = requests.get(url, headers=headers)
print(response.url)

# 出力は次のとおりです: https://www.baidu.com/s?wd=%E9%9B%A8%E9%9C%93%E5

%90%8C%E5%AD%A6&pn=1

2.3 GET リクエストを使用して Web ページをクロールする

上記のリクエストリンクは JSON 形式の文字列を返すため、通常の Web ページをリクエストすると、対応するコンテンツが確実に取得されます。

import requests
import re
headers = {"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’}
response = requests.get(’https://www.zhihu.com/explore’, headers=headers)
result = re.findall("(ExploreSpecialCard-contentTitle|ExploreRoundtableCard
questionTitle).*?>(.*?)</a>", response.text)
print([i[1] for i in result])

[ 「西安回民街のおいしいものは何ですか?」' , ' 西安で訪れる価値のある宝物店は何ですか?' 、 'あなたの青春を運ぶ西安の商業地区はどこですか? ' 、' 共有できる良い運転習慣は何ですか? ' , ' 経験豊富なドライバーだけが知っている運転のヒントはありますか?」、「車を持っている人は注意してください。誰もがこれらの運転知識を習得する必要があります。重要な瞬間に命を救うことができます。」、「ランディングへようこそ!志湖会員募集のお知らせ』、『惑星着陸の質問:未来に旅行するのに10元を与えますが、どうやって生計を立てることができますか?' 、 '惑星着陸の質問: Zhihu 宇宙でどの種類の「超エネルギー」が最も欲しいですか? どのように使用しますか? 」 、 「ノルウェーのサーモン、産地が重要」 、 「ノルウェーの最も魅力的な場所はどこですか?」' , ' ノルウェーに住むのはどんな感じですか? ' 、' BOE の AMOLED フレキシブル スクリーンの量産についてどう思いますか? 将来の展望は何ですか?』、『フレキシブルスクリーンは携帯電話業界に革命を起こすことができるのか?' 、 '極薄で曲がるフレキシブルバッテリーとは?スマートフォンのバッテリー寿命に大きな影響を与えるでしょうか? ' , ' 芸術の基礎がまったくない状態で、どうすれば芸術を上手に学び、美術試験で高得点を獲得できますか? 」、「清華美術学院は軽蔑されているのですか?」、「美大生は本当に悪いのですか?」「人はこの人生をどう生きるべきなのか?」』、『人は人生で何を追求すべきなのか?』、『世界の究極の真実を知った時、人間は発狂するのか?』、『不安は能力不足のせいなのか?』、『対人恐怖症ってどんな体験?' , ' 「忙しいときは落ち込んでいる暇はない」という格言は合理的ですか?' ]

ここでは、ブラウザの識別情報である User-Agent フィールドの情報を含むヘッダー情報を追加しました。これを追加しない場合、Zhihu はクロールを禁止します。

バイナリ データの取得 上記の例では、実際には HTML ドキュメントを返す Zhihu ページを取得しています。

写真、オーディオ、ビデオ、その他のファイルを取得したい場合はどうすればよいですか? 写真、音声、ビデオなどのファイルは基本的にバイナリ コードで構成されており、特定の保存形式とそれに対応する解析方法により、さまざまなマルチメディアを見ることができます。

したがって、それらを取得したい場合は、バイナリ コードを取得する必要があります。GitHub のサイト アイコンを例に挙げてみましょう。

import requests
response = requests.get("https://github.com/favicon.ico")
with
open(’github.ico’, ’wb’) as f:
f.write(response.content)

Response オブジェクトの 2 つのプロパティは、text と content で、前者は文字列型のテキストを表し、後者はバイト型のデータを表します。同様に、オーディオ ファイルやビデオ ファイルもこの方法で取得できます。

2.4 ヘッダーパラメータでクッキーを運ぶ

Web サイトでは、ユーザーのアクセス状況を維持するためにリクエスト ヘッダーの Cookie フィールドがよく使用されるため、ヘッダー パラメーターに Cookie を追加して、一般ユーザーのリクエストをシミュレートできます。

2.4.1 Cookieの取得

クローラーを通じてログイン ページを取得できるようにするため、または Cookie を通じてクロール防止を解決するには、リクエストを使用して Cookie 関連のリクエストを処理する必要があります。

import requests
url = ’https://www.baidu.com’
req = requests.get(url)
print(req.cookies)
# 响应的cookies
for key, value in req.cookies.items():
print(f"{key} = {value}") 

<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>

BDORZ = 27315

ここでは、最初に cookies 属性を呼び出すことで Cookie を正常に取得でき、その型が RequestCookieJar であることがわかります。次に items() メソッドを使用してタプルのリストに変換し、各 Cookie の名前と値を走査して出力し、Cookie の走査と分析を実現します。

2.4.2 Cookieを使用したログイン

Cookie とセッションを導入する利点: ログイン後にページをリクエストできるようになります。

Cookie とセッションを持ち込むことの欠点: 一連の Cookie とセッションはユーザーのリクエストにすぐに対応することが多く、リクエストの数が多すぎるため、サーバーによって簡単にクローラーとして認識されます。

Cookie が必要ない場合は Cookie を使用しないようにしてください。ただし、ログイン後にページを取得するには、Cookie を使用してリクエストを送信する必要があります。ログイン状態を維持するために Cookie を直接使用できます。Zhihu を例として説明します。 。まず Zhihu にログインし、ヘッダーの Cookie コンテンツをコピーします。

➢ ユーザーエージェントとクッキーをブラウザからコピー

➢ ブラウザのリクエストヘッダフィールドと値は、headers パラメータと一致している必要があります。

➢ ヘッダリクエストパラメータ辞書のCookieキーに対応する値は文字列である

import requests
import re
# 构造请求头字典
headers = {
# 从浏览器中复制过来的User-Agent
"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (
KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’,
# 从浏览器中复制过来的Cookie
"cookie": ’xxx这里是复制过来的cookie字符串’}
# 请求头参数字典中携带cookie字符串
response = requests.get(’https://www.zhihu.com/creator’, headers=headers)
data = re.findall(’CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>’,response.text)
print(response.status_code)
print(data)

Cookie を使用せずにリクエストを行う場合:

import requests
import re
headers = {"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’}
response = requests.get(’https://www.zhihu.com/creator’, headers=headers)
data = re.findall(’CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>’,response.text)
print(response.status_code)
print(data)

200

[]

印刷出力では空になっていますが、この 2 つと比較すると、headers パラメーターは、ログイン後にのみアクセスできるページを取得するために Cookie を運ぶために正常に使用されています。

2.4.3 Cookieパラメータの使用

前のセクションでは、ヘッダー パラメーターに Cookie を含めましたが、特別な Cookie パラメーターを使用することもできます。

❖ 1. Cookie パラメータの形式: 辞書

cookies = "cookie の名前":"cookie の値"

➢ 辞書はリクエストヘッダーの Cookie 文字列に対応し、辞書のキーと値のペアの各ペアはセミコロンとスペースで区切られます。

➢ 等号の左側は Cookie の名前で、Cookie 辞書のキーに対応します。

➢ 等号の右側は Cookie 辞書の値に対応します

❖ 2. Cookieのパラメータの使用方法

応答 = request.get(url, cookie)

❖ 3. Cookie 文字列を Cookie パラメータに必要な辞書に変換します。

cookies_dict = { クッキー . 分割 ( '=' ) [ 0 ]: クッキー 。クッキーの場合は、split ( '=' ) [- 1 ]

クッキー_str 。スプリット ( '; ' ) }

❖ 4. 注: Cookie には通常有効期限があり、有効期限が切れると再度取得する必要があります。

response = requests.get(url, cookies)
import requests
import re
url = ’https://www.zhihu.com/creator’
cookies_str = ’复制的cookies’
headers = {"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’}
cookies_dict = {cookie.split(’=’, 1)[0]:cookie.split(’=’, 1)[-1] for cookie in
cookies_str.split(’; ’)}
# 请求头参数字典中携带cookie字符串
resp = requests.get(url, headers=headers, cookies=cookies_dict)
data = re.findall(’CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>’,resp.text)
print(resp.status_code)
print(data)

200

[ 'Python で、ID は異なるが統合として同じクラスを使用してこのメ​​ソッドを記述するにはどうすればよいですか? ' 、' 両親にはコンピューターを買ってくれるお金がないのですが、どうすればよいでしょうか? ' , ' 現在の生活状況を一文で説明してください。' ]

2.4.4 Cookie を設定するために RequestsCookieJar オブジェクトを構築する

ここでは、RequestsCookieJar オブジェクトを構築して Cookie を設定することもできます。サンプル コードは次のとおりです。

import requests
import re
url = ’https://www.zhihu.com/creator’
cookies_str = ’复制的cookies’
headers = {"user-agent": ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36’}
jar = requests.cookies.RequestsCookieJar()
for cookie in cookies_str.split(’;’):
key,value = cookie.split(’=’,1)
jar. set(key,value)
# 请求头参数字典中携带cookie字符串
resp = requests.get(url, headers=headers, cookies=jar)
data = re.findall(’CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>’,resp.text)
print(resp.status_code)
print(data)

200

[ 'Python で、ID は異なるが統合として同じクラスを使用してこのメ​​ソッドを記述するにはどうすればよいですか? ' 、' 両親にはコンピューターを買ってくれるお金がないのですが、どうすればよいでしょうか? ' , ' 現在の生活状況を一文で説明してください。' ]

ここでは、まず新しい RequestCookieJar オブジェクトを作成し、次に、split() メソッドを使用してコピーした Cookie を分割し、次に set() メソッドを使用して各 Cookie のキーと値を設定し、次にリクエストの get() メソッドを呼び出し、 pass Cookie パラメータを与えるだけです。

もちろん、Zhihu 独自の制限により、headers パラメータも必須ですが、元の headers パラメータに cookie フィールドを設定する必要はありません。試してみたところ、Zhihuにも普通にログインできることが分かりました。

2.4.5 cookieJarオブジェクトをcookie辞書に変換する方法

リクエストで取得したresposneオブジェクトはcookie属性を持ちます。属性値は cookieJar タイプで、他のサーバーによって設定されたローカル Cookie が含まれます。これを Cookie の辞書に変換するにはどうすればよいでしょうか?

❖ 1. 変換方法

cookies_dict =requests.utils.dict_from_cookiejar(response.cookies)

❖ 2. response.cookies によって返されるオブジェクトは cookieJar タイプです

❖ 3.requests.utils.dict_from_cookiejar関数はCookie辞書を返します。

import requests
import re
url = 'https://www.zhihu.com/creator'
cookies_str = '复制的cookies'
headers = {"user-agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
cookie_dict = {cookie.split('=', 1)[0]:cookie.split('=', 1)[-1] for cookie in
cookies_str.split('; ')}
# 请求头参数字典中携带cookie字符串
resp = requests.get(url, headers=headers, cookies=cookies_dict)
data = re.findall('CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>',resp.text)
print(resp.status_code)
print(data)
# 可以把一个字典转化为一个requests.cookies.RequestsCookieJar对象
cookiejar = requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None,
overwrite=True)
type(cookiejar) # requests.cookies.RequestsCookieJar
type(resp.cookies) # requests.cookies.RequestsCookieJar
#构造RequestsCookieJar对象进行cookies设置其中jar的类型也是 requests.cookies.
RequestsCookieJar
#cookiejar转字典
requests.utils.dict_from_cookiejar(cookiejar)

2.5 タイムアウト設定

インターネットをサーフィンしていると、ネットワークの変動に遭遇することがよくありますが、このとき、長時間待機したリクエストがまだ結果を返さないことがあります。

クローラーでは、リクエストに対して長期間結果が得られない場合、プロジェクト全体の効率が非常に低くなります。このとき、リクエストは一定時間内に結果を返さなければならないように強制する必要があります。エラーが報告されます。

❖ 1. タイムアウトパラメータ timeout の使用方法

応答 = request.get(url, タイムアウト = 3)

❖ 2. timeout=3 は、リクエストの送信後、3 秒以内にレスポンスが返されます。それ以外の場合は例外がスローされます。

URL = 'http://www.tipdm.com/tipdm/index.html'

#タイムアウトを 2 に設定します

print('タイムアウトは 2:',requests.get(url,timeout=2))

タイムアウトが短すぎる場合、エラーが報告されます

request.get(url,timeout = 0.1) #時間は 0.001 であることに注意してください

タイムアウトは 2: <応答 [200]>

3. Request を使用して POST リクエストを送信します

考えてみます: POST リクエストをどこで使用するのでしょうか?

1. ログインと登録 (Web エンジニアの見解では、GET よりも POST の方が安全であり、ユーザーのアカウントのパスワードやその他の情報が URL アドレスに公開されることはありません)

2. 大きなテキストコンテンツを送信する必要がある場合(POSTリクエストはデータ長を必要としません)

したがって、同様に、クローラも、これら 2 つの場所で POST リクエストを送信するためにブラウザをシミュレートする必要があります。実際、POST リクエストの送信は GET メソッドと非常によく似ていますが、パラメータを定義する必要があります。データ:

POSTパラメータの説明:

post(url, data=None, json=None, **kwargs):

❖ URL: リクエストする URL

❖ data : (オプション) リクエストの本文で送信する辞書、タプルのリスト、バイト、またはファイルのようなオブジェクト

❖ json: (オプション) JSON データ。Request クラスの本体に送信されます。

❖ **kwargs: 可変長のキーワード引数

import requests
payload = {’key1’: ’value1’, ’key2’: ’value2’}
req = requests.post("http://httpbin.org/post", data=payload)
print(req.text)

3.1 POST は JSON データを送信します

送信したいデータがフォームとしてエンコードされていないことが多く、特に多くの Java URL をクロールするときにこの問題が発生することがわかりました。dict の代わりに文字列を渡すと、データは直接ポストされます。json.dumps() を使用して dict を str 形式に変換できます。ここでは、dict を自分でエンコードすることに加えて、json パラメーターを使用して直接渡すこともでき、自動的にエンコードされます。

import json
import requests
url = ’http://httpbin.org/post’
payload = {’some’: ’data’}
req1 = requests.post(url, data=json.dumps(payload))
req2 = requests.post(url, json=payload)
print(req1.text)
print(req2.text)

返された結果が正常に取得されたことがわかります。フォーム部分は送信されたデータであり、POST リクエストが正常に送信されたことを証明します。

ノート

リクエスト モジュールは、データ、json、および params の 3 つのパラメータを運ぶメソッドを使用してリクエストを送信します。

params は get リクエストで使用され、data と json は post リクエストで使用されます。

データが受け取ることができるパラメータは、辞書、文字列、バイト、ファイル オブジェクトです。

❖ ヘッダーで content-type を指定しない場合は、メッセージが str 型であるか dict 型であるかに関係なく、json パラメーターを使用します。

タイプ (デフォルトは application/json) です。

❖ data パラメーターを使用します。メッセージは dict タイプです。ヘッダーで content-type のタイプを指定しない場合、デフォルトの application/x

www-form-urlencoded は通常のフォームで送信するフォームと同等で、フォーム内のデータをキーと値のペアに変換しますが、この際のデータは request.POST とリクエストの内容から取得できます。このキーと値のペアの形式では、body は a=1&b= 2 です。

❖ data パラメータを使用します。メッセージは str タイプです。ヘッダーで content-type のタイプを指定しない場合、デフォルトは application/json です。

data パラメーターを使用してデータを送信する場合、request.body の内容は a=1&b=2 の形式になります。

json パラメータを使用してデータを送信する場合、request.body の内容は「"a": 1, "b": 2」の形式になります。

3.2 POSTファイルのアップロード

クローラーを使用してファイルをアップロードしたい場合は、fifile パラメーターを使用できます。

url = 'http://httpbin.org/post'
files = {'file': open('test.xlsx', 'rb')}
req = requests.post(url, files=files)
req.text

WEB 開発に精通したパートナーがいる場合は、非常に大きなファイルをマルチパート/フォーム データ リクエストとして送信する場合、そのリクエストをデータ ストリームにするとよいことを知っておく必要があります。デフォルトではリクエストはサポートされていないため、requests-toolbelt の 3 部構成ライブラリを使用できます。

3.3 POST リクエストを使用して Web ページをクロールする

主に解析対象のWebページを見つけるため

import requests
# 准备翻译的数据
kw =
input("请输入要翻译的词语:")
ps = {"kw": kw}
# 准备伪造请求
headers = {
# User-Agent:首字母大写,表示请求的身份信息;一般直接使用浏览器的身份信息,伪造
爬虫请求
# 让浏览器认为这个请求是由浏览器发起的[隐藏爬虫的信息]
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (
KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 Edg/85.0.564.41"
}
# 发送POST请求,附带要翻译的表单数据--以字典的方式进行传递
response = requests.post("https://fanyi.baidu.com/sug", data=ps)
# 打印返回的数据
# print(response.content)
print(response.content.decode("unicode_escape"))

4.高度なリクエスト(1)※セッションセッションメンテナンス

このパートでは、主にセッションの維持とプロキシ IP の使用について紹介します。

リクエストでは、get() や post() などのメソッドを直接使用すると、確かに Web ページリクエストをシミュレートできますが、これは実際には別のセッションと同等です。つまり、2 つのブラウザを使用して別のページを開くことになります。

このようなシナリオを想像してください。最初のリクエストでは post() メソッドを使用して特定の Web サイトにログインし、ログインに成功した後に個人情報を取得する 2 回目では、get() メソッドを使用して個人情報ページをリクエストします。また。実はこれはブラウザを2つ開いているのと同じで、まったく関係のないセッションなのですが、果たして個人情報は取得できるのでしょうか?もちろん違います。

 

友人の中には、2 つのリクエストに同じ Cookie を設定すれば十分ではないか、と言う人もいるかもしれません。はい、しかし、そうするのは面倒なので、もっと簡単な回避策があります。

実際、この問題を解決する主な方法は、同じセッションを維持することです。これは、新しいブラウザを開くのではなく、新しいブラウザ タブを開くのと同じです。でも、毎回 Cookie を設定したくないのですが、どうすればよいでしょうか? 現時点では、Session オブジェクトという新しい武器が追加されています。

これを使用すると、セッションを簡単に維持でき、Cookie について心配する必要がなく、自動的に処理されます。

リクエストモジュールのセッションクラスは、状態保存の目的を達成するために、リクエストの送信とレスポンスの取得のプロセス中に生成されるクッキーを自動的に処理できます。次にそれを学びに来ます。

4.1 request.session の役割と適用シナリオ

❖ request.session の役割

Cookie を自動的に処理します。つまり、次のリクエストで前の Cookie が取得されます。

❖ request.session の適用シナリオ

複数の連続したリクエスト中に生成された Cookie を自動的に処理する

4.2requests.sessionの使用方法

セッション インスタンスが Web サイトをリクエストした後、他のサーバーによって設定されたローカル Cookie がセッションに保存され、次回セッションを使用して他のサーバーをリクエストするときに、以前の Cookie が取得されます。

session = request .session () # セッションオブジェクトをインスタンス化する

応答 = セッション 。get ( URL 、ヘッダー、...)

応答 = セッション 。投稿 ( URL 、データ、...)

セッション オブジェクトによって送信される get または post リクエストのパラメーターは、request モジュールによって送信されるものとまったく同じです。

4.3 セッションを使用して github ログイン情報を維持する

❖ Github ログインのプロセス全体と、ログイン後にのみアクセスできるページへのアクセスをキャプチャします

❖ ログインリクエストの URL アドレス、リクエストメソッド、および必要なリクエストパラメータを決定します。

- 一部のリクエスト パラメータは、他の URL に対応する応答コンテンツ内にあり、re モジュールを使用して取得できます。

❖ ログイン後にのみアクセスできるページのURLアドレスとリクエスト方法を決定する

❖ request.session を使用したコード補完

import requests
import re
# 构造请求头字典
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (
KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36',}
# 实例化session对象
session = requests.session()
# 访问登陆页获取登陆请求所需参数
response = session.get(https://github.com/login, headers=headers)
authenticity_token = re.search('name="authenticity_token" value="(.*?)" />',
response.text).group(1) # 使用正则获取登陆请求所需参数
# 构造登陆请求参数字典
data = {
'commit': 'Sign in', # 固定值
'utf8': ' ', # 固定值
'authenticity_token': authenticity_token, # 该参数在登陆页的响应内容中
'login':
input('输入github账号:'),
'password':
input('输入github账号:')}
# 发送登陆请求(无需关注本次请求的响应)
session.post(https://github.com/session, headers=headers, data=data)
# 打印需要登陆后才能访问的页面
response = session.get(https://github.com/settings/profile, headers=headers)
print(response.text)

校正にはテキスト比較ツールを使用できます。

5.リクエストのアドバンス(2)※プロキシの利用

一部の Web サイトでは、テスト中に数回リクエストを行うと、コンテンツが正常に取得できるようになりました。ただし、大規模なクローリングが開始されると、大規模かつ頻繁なリクエストに対して、Web サイトが確認コードをポップアップ表示したり、ログイン認証ページにジャンプしたり、クライアントの IP を直接ブロックしたりして、一定期間アクセスできなくなる可能性があります。 。

これを防ぐには、この問題を解決するためにプロキシを設定する必要があります。それには、proxies パラメータを使用する必要があります。次のように設定できます。

proxy プロキシ パラメーターは、対応するプロキシ IP がプロキシ サーバーに送信するリクエストを転送するようにプロキシ IP を指定します。まず、プロキシ IP とプロキシ サーバーについて理解しましょう。

5.1 エージェントの使用プロセス

1. プロキシ IP はプロキシ サーバーを指す IP です。

2. プロキシ サーバーは、リクエストをターゲット サーバーに転送するのに役立ちます。

5.2 フォワードプロキシとリバースプロキシ

前述したように、proxy パラメーターで指定されたプロキシ IP はフォワード プロキシ サーバーを指すため、対応してリバース サーバーが存在します。ここで、フォワード プロキシ サーバーとリバース プロキシ サーバーの違いを理解しましょう。

❖ リクエストを送信する側の観点からフォワード プロキシとリバース プロキシを区別する

❖ ブラウザまたはクライアント (リクエストを送信する側) にリクエストを転送することをフォワード プロキシと呼びます

- ブラウザは、VPN など、最終的にリクエストを処理するサーバーの実際の IP アドレスを知っています。

❖ リクエストをブラウザやクライアント(リクエストを送信する側)に転送するのではなく、最終的にリクエストを処理するサーバー(リバースプロキシと呼ばれます)にリクエストを転送します。

- ブラウザは、nginx などのサーバーの実際のアドレスを知りません。

5.3 プロキシIP(プロキシサーバー)の分類

❖ プロキシ IP の匿名性の程度に応じて、プロキシ IP は次の 3 つのカテゴリに分類できます。

➢ 透過的プロキシ: 透過的プロキシはあなたの IP アドレスを直接「隠す」ことができますが、それでもあなたが誰であるかを知ることができます。

ターゲット サーバーが受信するリクエスト ヘッダーは次のとおりです。

REMOTE_ADDR = プロキシ IP

HTTP_VIA = プロキシ IP

HTTP_X_FORWARDED_FOR = あなたのIP

➢ 匿名プロキシ (Anonymous Proxy): 匿名プロキシを使用すると、他の人はあなたがプロキシを使用していることだけを知ることができ、あなたが誰であるかを知ることはできません。

ターゲット サーバーが受信するリクエスト ヘッダーは次のとおりです。

REMOTE_ADDR = プロキシ IP

HTTP_VIA = プロキシ IP

HTTP_X_FORWARDED_FOR = プロキシ IP

➢ 高匿名性プロキシ (エリート プロキシまたは高匿名性プロキシ): 高匿名性プロキシでは、他の人がプロキシを使用していることを知ることができないため、最良の選択です。** 知名度の高いプロキシを使用するのが最も効果的であることに疑いの余地はありません**。

ターゲット サーバーが受信するリクエスト ヘッダーは次のとおりです。

REMOTE_ADDR = プロキシ IP

HTTP_VIA = 未定

HTTP_X_FORWARDED_FOR = 未定

❖ Web サイトが使用するプロトコルによっては、対応するプロトコルのプロキシサービスが必要です。

プロキシからのリクエストを処理するために使用されるプロトコルは、次のように分類できます。

➢ http プロキシ: ターゲット URL は http プロトコルです

➢ https プロキシ: ターゲット URL は https プロトコルです

➢ Socks トンネル プロキシ (socks5 プロキシなど) など:

✾ 1. Socks プロキシは、アプリケーション プロトコル (FTP、HTTP、HTTPS など) に関係なく、単純にデータ パケットを送信します。

✾ 2. Socks プロキシは、http および https プロキシよりも時間がかかりません。

✾ 3. Socks プロキシは http および https リクエストを転送できます

5.4 プロキシのプロキシパラメータの使用

リクエストしているのは同じクライアントではないとサーバーに認識させるため、ドメイン名への頻繁なリクエストがブロックされないようにするには、プロキシ IP を使用する必要があります。その後、リクエストの基本的な使用方法を学びます。モジュールはプロキシ IP を使用します。

response = requests . get ( url , proxies = proxies )
proxies 的形式:字典
proxies = {
" http ": " http :// 12.34.56.79: 9527 ",
" https ": " https :// 12.34.56.79: 9527 ",
}

注: プロキシ ディクショナリに複数のキーと値のペアが含まれている場合、リクエストの送信時に URL アドレスのプロトコルに従って、対応するプロキシ IP が選択されます。

import requests
proxies = {
"http": "http://124.236.111.11:80",
"https": "https:183.220.145.3:8080"}
req = requests.get(’http://www.baidu.com’,proxies =proxies)
req.status_code

6. 高度なリクエスト (3)*SSL証明書検証

さらに、リクエストは証明書検証の機能も提供します。HTTP リクエストを送信すると、SSL 証明書がチェックされます。verify パラメータを使用して、この証明書をチェックするかどうかを制御できます。実際、verify パラメータが追加されていない場合、デフォルトは True であり、動的に検証されます。

次に、リクエストを使用してテストしてみましょう。

import requests
url = 'https://cas.xijing.edu.cn/xjtyrz/login'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
req = requests.get(url,headers=headers)

SSLエラー: HTTPSConnectionPool(host= 'cas.xijing.edu.cn' 、port=443): 最大再試行回数

URL: /xjtyrz/login で超過しました (SSLError(SSLCertVerificationError(1,

'[SSL: CERTIFICATE_VERIFY_FAILED] 証明書の検証に失敗しました: 取得できません

ローカル発行者証明書 (_ssl.c:1123)' )))

ここでは、証明書検証エラーを示すエラー SSL エラーが表示されます。では、HTTPS サイトがリクエストされたにもかかわらず、証明書が間違ったページを検証した場合、そのようなエラーが報告されることになります。このエラーを回避するにはどうすればよいでしょうか? 非常に簡単で、verify パラメータを False に設定します。

関連するコードは次のとおりです。

import requests
url = 'https://www.jci.edu.cn/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
req = requests.get(url,headers=headers,verify=False)
req.status_code

200

SSL 認証が必要な Web ページが見つかりません。本当に怒っています。

ただし、警告が報告されており、それに証明書を割り当てるよう提案されていることがわかりました。警告を無視するように設定することで、この警告をブロックできます。

import requests
from requests.packages import urllib3
urllib3.disable_warnings()
url = 'https://www.jci.edu.cn/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
req = requests.get(url,headers=headers,verify=False)
req.status_code

200

または、警告をログにキャプチャして無視します。

import logging
import requests
logging.captureWarnings(True)
url = 'https://www.jci.edu.cn/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
req = requests.get(url,headers=headers,verify=False)
req.status_code

200

もちろん、クライアント証明書として使用するローカル証明書を指定することもできます。これは、単一のファイル (キーと証明書を含む) または 2 つのファイル パスを含むタプルにすることができます。

import requests
response = requests.get(https://www.12306.cn’,cert=(’./path/server.crt’,’/path/key
))
print(response.status_code)

200

もちろん、上記のコードはデモンストレーションの例であり、crt ファイルとキー ファイルが必要で、それらのパスを指定する必要があります。ローカル秘密証明書のキーは復号化された状態である必要があり、暗号化された状態のキーはサポートされていないことに注意してください。このような URL は今ではほとんどありません。

7. リクエストライブラリのその他のコンテンツ

7.1 応答内容の表示

リクエストを送信すると、当然のことながらレスポンスが得られます。上の例では、テキストとコンテンツを使用して応答のコンテンツを取得しました。さらに、ステータス コード、応答ヘッダー、Cookie など、他の情報を取得するために使用できるプロパティとメソッドが多数あります。

例は次のとおりです。

import requests
url = 'https://www.baidu.com'
req = requests.get(url)
print(req.status_code)
# 响应状态码
print(req.text)
# 响应的文本内容
print(req.content)
# 响应的二进制内容
print(req.cookies)
# 响应的cookies
print(req.encoding)
# 响应的编码
print(req.headers)
# 响应的头部信息
print(req.url)
# 响应的网址
print(req.history)
# 响应的历史

7.2 ステータスコードとエンコーディングの表示

サーバーから返されたステータス コードを表示するには、rqg.status_code の形式を使用し、サーバーから返された HTTP ヘッダー情報を通じて Web ページをエンコードするには、rqg.encoding の形式を使用します。Requests ライブラリの推測が間違っている場合は、返される Web ページ コンテンツの文字化けを避けるためにエンコード コードを手動で指定する必要があることに注意してください。

7.3 get リクエストを送信し、エンコーディングを手動で指定する

コード 1-2: get リクエストを送信し、エンコーディングを手動で指定します。

url = 'http://www.tipdm.com/tipdm/index.html'
rqg = requests.get(url)
print('状态码 ',rqg.status_code)
print('编码 ',rqg.encoding)
rqg.encoding = 'utf-8' #手动指定编码
print('修改后的编码 ',rqg.encoding)
# print(rqg.text)

ステータスコード

200

コーディング

ISO-8859-1

変更されたエンコーディング

UTF-8

ノート

手動で指定する方法は柔軟性がなく、クローリング プロセスでさまざまな Web ページ エンコーディングに適応できませんが、chardet ライブラリを使用する方法は比較的シンプルで柔軟性があります。chardet ライブラリは、非常に優れた文字列/ファイル エンコーディング検出モジュールです。

7.4 シャルデライブラリの使用

chartdet ライブラリの detect メソッドは、指定された文字列のエンコーディングを検出できます。その構文は次のとおりです。

chartdet.detect(byte_str)

共通パラメータと検出メソッドの説明

byte_str: 受信文字列。検出するエンコーディングを表す文字列。デフォルトなし

7.5 detect メソッドを使用してエンコーディングを検出し、指定する

コード 1-3: detect メソッドを使用してエンコードを検出し、エンコードを指定します

import chardet
url = 'http://www.tipdm.com/tipdm/index.html'
rqg = requests.get(url)
print(rqg.encoding)
print(chardet.detect(rqg.content))
rqg.encoding = chardet.detect(rqg.content)['encoding']
# 访问字典元素
print(rqg.encoding)

ISO-8859-1

{ 'エンコーディング' : 'utf-8' 、 '信頼性' : 0.99、 '言語' : '' }

UTF-8

7.6 リクエストライブラリ総合テスト

リンク、リクエスト ヘッダー、応答ヘッダー、タイムアウト、ステータス コードを含む完全な GET リクエストを Web サイト「http://www.tipdm.com/tipdm/index.html」に送信します。エンコードは正しく設定されています。

リスト 1-6: 完全な HTTP リクエストを生成します。

# 导入相关的库
import requests
import chardet
# 设置url
url = 'http://www.tipdm.com/tipdm/index.html'
# 设置请求头
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36"}
# 生成GET请求,并设置延时为2
rqg = requests.get(url,headers=headers,timeout = 2)
# 查看状态码
print("状态码 ",rqg.status_code)
# 检测编码(查看编码)
print('编码 ',rqg.encoding)
# 使用chardet库的detect方法修正编码
rqg.encoding = chardet.detect(rqg.content)['encoding']
# 检测修正后的编码
print('修正后的编码: ',rqg.encoding)
#查看响应头
print('响应头:',rqg.headers)
# 查看网页内容
#print(rqg.text)

ステータスコード

200

コーディング

ISO-8859-1

修正されたエンコード: utf-8

応答ヘッダー: { 'Date' : 'Mon, 18 Nov 2019 06:28:56 GMT' , 'Server' : 'Apache-Coyote/1.1' , '

Accept-Ranges' : 'bytes' 、 'ETag' : 'W/"15693-1562553126764"' 、 'Last-Modified' : '

Mon, 08 Jul 2019 02:32:06 GMT' , 'Content-Type' : 'text/html' , 'Content-Length' : '

15693' , 'キープアライブ' : 'タイムアウト=5、最大=100' , '接続' : 'キープアライブ' }

おすすめ

転載: blog.csdn.net/y1282037271/article/details/129169619