我需要抓取一个网站,但在抓取之前我需要登录。
我似乎需要输入三样东西:用户名、密码和真实性 token 。我知道用户名和密码,但我不知道如何访问 token 。
这是我尝试过的:
import requests
from lxml import html
login_url = "https://urs.earthdata.nasa.gov/home"
session_requests = requests.session()
result = session_requests.get(login_url)
tree = html.fromstring(result.text)
authenticity_token = list(set(tree.xpath("//input[@name='authenticity_token']/@value")))[0]
payload = {"username": "my_name",
"password": "my_password",
"authenticity_token": authenticity_token}
result = session_requests.post(
login_url,
data = payload,
headers = dict(referer=login_url)
)
print (result)
这会导致:
<Response [404]>
我的名字和密码输入正确,所以肯定是 token 出了问题。我认为问题出在这一行:
authenticity_token = list(set(tree.xpath("//input[@name='authenticity_token']/@value")))[0]
或这一行:
payload = {"username": "my_name",
"password": "my_password",
"authenticity_token": authenticity_token}
通过查看网页上的源代码,我注意到有一个 authenticity_token
, csrf-token
和一个 csrf-param
。所以它们的顺序可能是错误的,但我尝试了所有的组合。
编辑:
这是一个漂亮的汤方法,它再次导致 404。
s = requests.session()
response = s.get(login_url)
soup = BeautifulSoup(response.text, "lxml")
for n in soup('input'):
if n['name'] == 'authenticity_token':
token = n['value']
if n['name'] == 'utf8':
utf8 = n['value']
break
auth = {
'username': 'my_username'
, 'password': 'my_password'
, 'authenticity_token': token
, 'utf8' : utf8
}
s.post(login_url, data=auth)
最佳答案
如果您检查页面,您会发现表单操作值为 '/login'
,因此您必须将数据提交到 https://urs.earthdata.nasa。政府/登录'
。
login_url = "https://urs.earthdata.nasa.gov/login"
home_url = "https://urs.earthdata.nasa.gov/home"
s = requests.session()
soup = BeautifulSoup(s.get(home_url).text, "lxml")
data = {i['name']:i.get('value', '') for i in soup.find_all('input')}
data['username'] = 'my_username'
data['password'] = 'my_password'
result = s.post(login_url, data=data)
print(result)
< Response [200]>
一个简单的例子 selenium
:
from selenium import webdriver
driver = webdriver.Firefox()
url = 'https://n5eil01u.ecs.nsidc.org/MOST/MOD10A1.006/'
driver.get(url)
driver.find_element_by_name('username').send_keys('my_username')
driver.find_element_by_name('password').send_keys('my_password')
driver.find_element_by_id('login').submit()
html = driver.page_source
driver.quit()
关于python - 身份验证结果为 404 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46530657/