网络抓取 python 请求 post 请求
web scraping with python requests post request
我正在尝试抓取 this 网站,该网站提供了提交表格的许可证号信息。
我正在尝试模拟 POST 请求,但每次它发送响应“未找到数据”时,我都使用了每个 header 和有效负载,但仍然没有任何效果
我查看了“网络”选项卡并尝试了每个请求 header 但它仍然无法正常工作。我完全迷路了。
这是我的代码
import json
import requests
from requests import Session
session = Session()
headers = {
"Accept":"*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9,hi;q=0.8",
"Connection": "keep-alive",
"Content-Length": "39",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
#"Cookie": "PHPSESSID=l98qcansg3shogj29o14mt1opi; _ga=GA1.2.905847747.1646590237; _gid=GA1.2.153711160.1646590237",
#"DNT": "1",
"Host": "vahaninfos.com",
"Origin": "https://vahaninfos.com",
"Referer": "https://vahaninfos.com/vehicle-details-by-number-plate",
#"sec-ch-ua": """ " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98" """,
#"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "Windows",
"X-Requested-With": "XMLHttpRequest",
#"Sec-Fetch-Mode" :"cors",
#"Sec-Fetch-Dest": "empty",
"num":"NDQ4MTg3MjMw",
#"Sec-Fetch-Site":"same-origin"
}
payload = {
"number":"UP32AT5472",
"g-recaptcha-response":""
}
url = "https://vahaninfos.com/getdetails.php"
res = requests.post(url, data=json.dumps(payload), headers=headers, verify=False)
print(res.content)
如果你想试试这个网站你可以尝试输入这个UP32AT5471
然后自己看看输出
Chrome DevTools 上的网络选项卡
有效载荷
常规选项卡
提前致谢
此页面使用 PHPSESSIONID
发送 cookie,在 HTML
中它发送 token
这样的
<script>token = "NDQ4MTg3MjMw"
并使用 JavaScript
获取此值并添加 headers
num: NDQ4MTg3MjMw,
并且服务器需要 PHPSESSIONID
和 num
才能发送数据。
每个连接都会在 PHPSESSIONID
和 token
中创建新值 - 因此您可以在代码中硬编码一些值,但 session ID 只能在几分钟内有效 - 并且最好在 POST
请求之前从 GET
请求中获取新值。
所以你必须使用 requests.Session
与 cookies
一起工作,并首先将 GET
发送到 https://vahaninfos.com/vehicle-details-by-number-plate
以获取 cookie PHPSESSIONID
和 HTML
<script>token = "..."
接下来您必须从 HTML
获取此 token
- 即。使用 regex
- 并在 POST
请求中将其添加为 header num: ....
。
似乎其他 header 并不重要 - 甚至 X-Requested-With
。
此页面需要将数据作为 form
发送,因此您需要 data=payload
而不是 data=json.load(payload)
。它会自动创建具有正确值的 headers Content-Type
和 Content-Length
。
import requests
import re
session = requests.Session()
# --- GET ---
headers = {
# "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0",
}
url = "https://vahaninfos.com/vehicle-details-by-number-plate"
res = session.get(url, verify=False)
number = re.findall('token = "([^"]*)"', res.text)[0]
# --- POST ---
headers = {
# "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0",
# "X-Requested-With": "XMLHttpRequest",
'num': number,
}
payload = {
"number": "UP32AT5472",
"g-recaptcha-response": "",
}
url = "https://vahaninfos.com/getdetails.php"
res = session.post(url, data=payload, headers=headers, verify=False)
print(res.text)
结果:
<tr><td>Registration Number</td><td>:</td><td>UP32AT5472</td></tr>
<tr><td>Registration Authority</td><td>:</td><td>LUCKNOW</td></tr>
<tr><td>Registration Date</td><td>:</td><td>2003-06-06</td></tr>
<tr><td>Chassis Number</td><td>:</td><td>487530</td></tr>
<tr><td>Engine Number</td><td>:</td><td>490062</td></tr>
<tr><td>Fuel Type</td><td>:</td><td>PETROL</td></tr>
<tr><td>Engine Capacity</td><td>:</td><td></td></tr>
<tr><td>Model/Model Name</td><td>:</td><td>TVS VICTOR</td></tr>
<tr><td>Color</td><td>:</td><td></td></tr>
<tr><td>Owner Name</td><td>:</td><td>HARI MOHAN PANDEY</td></tr>
<tr><td>Ownership Type</td><td>:</td><td></td></tr>
<tr><td>Financer</td><td>:</td><td>CENTRAL BANK OF INDIA</td></tr>
<tr><td>Vehicle Class</td><td>:</td><td>M-CYCLE/SCOOTER(2WN)</td></tr>
<tr><td>Fitness/Regn Upto</td><td>:</td><td></td></tr>
<tr><td>Insurance Company</td><td>:</td><td>NATIONAL INSURANCE CO LTD.</td></tr>
<tr><td>Insurance Policy No</td><td>:</td><td>4165465465465</td></tr>
<tr><td>Insurance expiry</td><td>:</td><td>2004-06-05</td></tr>
<tr><td>Vehicle Age</td><td>:</td><td></td></tr>
<tr><td>Vehicle Type</td><td>:</td><td></td></tr>
<tr><td>Vehicle Category</td><td>:</td><td></td></tr>
现在您可以使用 beautifulsoup
或 lxml
(或其他模块)从 HTML
.
获取值
from bs4 import BeautifulSoup
soup = BeautifulSoup(res.text, 'html.parser')
for row in soup.find_all('tr'):
cols = row.find_all('td')
key = cols[0].text
val = cols[-1].text
print(f'{key:22} | {val}')
结果:
Registration Number | UP32AT5472
Registration Authority | LUCKNOW
Registration Date | 2003-06-06
Chassis Number | 487530
Engine Number | 490062
Fuel Type | PETROL
Engine Capacity |
Model/Model Name | TVS VICTOR
Color |
Owner Name | HARI MOHAN PANDEY
Ownership Type |
Financer | CENTRAL BANK OF INDIA
Vehicle Class | M-CYCLE/SCOOTER(2WN)
Fitness/Regn Upto |
Insurance Company | NATIONAL INSURANCE CO LTD.
Insurance Policy No | 4165465465465
Insurance expiry | 2004-06-05
Vehicle Age |
Vehicle Type |
Vehicle Category |
编辑:
在 运行 代码几次之后 POST
开始只向我发送值 R
- 也许它需要一些其他的 header 来隐藏机器人(即 User-Agent
), 或者有时可能需要为 ReCaptcha
.
发送正确的代码
至少在 Chrome 它停止发送 R
当我设置 ReCaptha
.
但是Firefox
还是发送R
.
最初我使用的是 Firefox
中的 User-Agent
,它可能会记住它。
编辑:
如果我使用的 User-Agent
与我的 Firefox
不同,那么代码会再次获得正确的值,而 Firefox
仍然只会获得 R
.
headers = {
"User-Agent": "Mozilla/5.0",
}
所以看起来代码可能需要在每个隐藏机器人的请求中使用随机 User-Agent
。
我正在尝试抓取 this 网站,该网站提供了提交表格的许可证号信息。 我正在尝试模拟 POST 请求,但每次它发送响应“未找到数据”时,我都使用了每个 header 和有效负载,但仍然没有任何效果 我查看了“网络”选项卡并尝试了每个请求 header 但它仍然无法正常工作。我完全迷路了。
这是我的代码
import json
import requests
from requests import Session
session = Session()
headers = {
"Accept":"*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9,hi;q=0.8",
"Connection": "keep-alive",
"Content-Length": "39",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
#"Cookie": "PHPSESSID=l98qcansg3shogj29o14mt1opi; _ga=GA1.2.905847747.1646590237; _gid=GA1.2.153711160.1646590237",
#"DNT": "1",
"Host": "vahaninfos.com",
"Origin": "https://vahaninfos.com",
"Referer": "https://vahaninfos.com/vehicle-details-by-number-plate",
#"sec-ch-ua": """ " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98" """,
#"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "Windows",
"X-Requested-With": "XMLHttpRequest",
#"Sec-Fetch-Mode" :"cors",
#"Sec-Fetch-Dest": "empty",
"num":"NDQ4MTg3MjMw",
#"Sec-Fetch-Site":"same-origin"
}
payload = {
"number":"UP32AT5472",
"g-recaptcha-response":""
}
url = "https://vahaninfos.com/getdetails.php"
res = requests.post(url, data=json.dumps(payload), headers=headers, verify=False)
print(res.content)
如果你想试试这个网站你可以尝试输入这个UP32AT5471
然后自己看看输出
Chrome DevTools 上的网络选项卡
有效载荷
常规选项卡
此页面使用 PHPSESSIONID
发送 cookie,在 HTML
中它发送 token
这样的
<script>token = "NDQ4MTg3MjMw"
并使用 JavaScript
获取此值并添加 headers
num: NDQ4MTg3MjMw,
并且服务器需要 PHPSESSIONID
和 num
才能发送数据。
每个连接都会在 PHPSESSIONID
和 token
中创建新值 - 因此您可以在代码中硬编码一些值,但 session ID 只能在几分钟内有效 - 并且最好在 POST
请求之前从 GET
请求中获取新值。
所以你必须使用 requests.Session
与 cookies
一起工作,并首先将 GET
发送到 https://vahaninfos.com/vehicle-details-by-number-plate
以获取 cookie PHPSESSIONID
和 HTML
<script>token = "..."
接下来您必须从 HTML
获取此 token
- 即。使用 regex
- 并在 POST
请求中将其添加为 header num: ....
。
似乎其他 header 并不重要 - 甚至 X-Requested-With
。
此页面需要将数据作为 form
发送,因此您需要 data=payload
而不是 data=json.load(payload)
。它会自动创建具有正确值的 headers Content-Type
和 Content-Length
。
import requests
import re
session = requests.Session()
# --- GET ---
headers = {
# "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0",
}
url = "https://vahaninfos.com/vehicle-details-by-number-plate"
res = session.get(url, verify=False)
number = re.findall('token = "([^"]*)"', res.text)[0]
# --- POST ---
headers = {
# "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0",
# "X-Requested-With": "XMLHttpRequest",
'num': number,
}
payload = {
"number": "UP32AT5472",
"g-recaptcha-response": "",
}
url = "https://vahaninfos.com/getdetails.php"
res = session.post(url, data=payload, headers=headers, verify=False)
print(res.text)
结果:
<tr><td>Registration Number</td><td>:</td><td>UP32AT5472</td></tr>
<tr><td>Registration Authority</td><td>:</td><td>LUCKNOW</td></tr>
<tr><td>Registration Date</td><td>:</td><td>2003-06-06</td></tr>
<tr><td>Chassis Number</td><td>:</td><td>487530</td></tr>
<tr><td>Engine Number</td><td>:</td><td>490062</td></tr>
<tr><td>Fuel Type</td><td>:</td><td>PETROL</td></tr>
<tr><td>Engine Capacity</td><td>:</td><td></td></tr>
<tr><td>Model/Model Name</td><td>:</td><td>TVS VICTOR</td></tr>
<tr><td>Color</td><td>:</td><td></td></tr>
<tr><td>Owner Name</td><td>:</td><td>HARI MOHAN PANDEY</td></tr>
<tr><td>Ownership Type</td><td>:</td><td></td></tr>
<tr><td>Financer</td><td>:</td><td>CENTRAL BANK OF INDIA</td></tr>
<tr><td>Vehicle Class</td><td>:</td><td>M-CYCLE/SCOOTER(2WN)</td></tr>
<tr><td>Fitness/Regn Upto</td><td>:</td><td></td></tr>
<tr><td>Insurance Company</td><td>:</td><td>NATIONAL INSURANCE CO LTD.</td></tr>
<tr><td>Insurance Policy No</td><td>:</td><td>4165465465465</td></tr>
<tr><td>Insurance expiry</td><td>:</td><td>2004-06-05</td></tr>
<tr><td>Vehicle Age</td><td>:</td><td></td></tr>
<tr><td>Vehicle Type</td><td>:</td><td></td></tr>
<tr><td>Vehicle Category</td><td>:</td><td></td></tr>
现在您可以使用 beautifulsoup
或 lxml
(或其他模块)从 HTML
.
from bs4 import BeautifulSoup
soup = BeautifulSoup(res.text, 'html.parser')
for row in soup.find_all('tr'):
cols = row.find_all('td')
key = cols[0].text
val = cols[-1].text
print(f'{key:22} | {val}')
结果:
Registration Number | UP32AT5472
Registration Authority | LUCKNOW
Registration Date | 2003-06-06
Chassis Number | 487530
Engine Number | 490062
Fuel Type | PETROL
Engine Capacity |
Model/Model Name | TVS VICTOR
Color |
Owner Name | HARI MOHAN PANDEY
Ownership Type |
Financer | CENTRAL BANK OF INDIA
Vehicle Class | M-CYCLE/SCOOTER(2WN)
Fitness/Regn Upto |
Insurance Company | NATIONAL INSURANCE CO LTD.
Insurance Policy No | 4165465465465
Insurance expiry | 2004-06-05
Vehicle Age |
Vehicle Type |
Vehicle Category |
编辑:
在 运行 代码几次之后 POST
开始只向我发送值 R
- 也许它需要一些其他的 header 来隐藏机器人(即 User-Agent
), 或者有时可能需要为 ReCaptcha
.
至少在 Chrome 它停止发送 R
当我设置 ReCaptha
.
但是Firefox
还是发送R
.
最初我使用的是 Firefox
中的 User-Agent
,它可能会记住它。
编辑:
如果我使用的 User-Agent
与我的 Firefox
不同,那么代码会再次获得正确的值,而 Firefox
仍然只会获得 R
.
headers = {
"User-Agent": "Mozilla/5.0",
}
所以看起来代码可能需要在每个隐藏机器人的请求中使用随机 User-Agent
。