首页 > 解决方案 > 登录后使用请求下载运行时文件

问题描述

我是网络抓取的新手,我想在登录后下载运行时 csv 文件(按钮没有 URL,它使用 JS 功能),我尝试使用https://curl.trillworks.com/#,它可以工作很好,但它使用动态cookies。

import requests

cookies = {
    ...,
}

headers = {
    ...
}

data = {
    ...
}

s = requests.Session()
response = s.post(posturl, headers=headers, cookies=cookies, data=data, verify=False)

Cookies 是动态的,所以每次我想下载文件时,我都必须获取新的 cookie,所以我尝试了使用相同脚本的不同方法

payload = {
  'login': 'login',
  'username': 'My_name',
  'password': 'My_password',
}

logurl = "http:..."
posturl = 'http:...'

s = requests.Session()
response = s.post(logurl, headers=headers, data=data)
# response = s.post(posturl, data=payload,auth=(my_name, my_password)) #This too gives me the wrong output

但这并没有给我正确的输出,它给了我第一页文本/html,响应标题给了我两种不同的内容类型

print response.headers['Content-Type'] 

正确的输出是'text/csv;charset=UTF-8',但它给了我信息'text/html;charset=UTF-8'status_code for both is 200CSV文件的posturl与html页面相同

标签: pythonweb-scrapingbeautifulsouppython-requestsrequest

解决方案


经过深入搜索,我发现:网络抓取有完全不同的工具:

1. requestor urllib: 广泛使用的工具,它使我们可以使用...进行发布和获取请求、登录、创建持久性 cookie Session(),我们可以使用一个很棒的工具curl访问https://curl.trillworks.com/,但这对于复杂的数据提取是不够的。

  1. Beautifullsoupor lxml:使用 for HTML Parser,在源 html 中导航,类似正则表达式以从 HTML 页面中提取所需元素get Title,找到div with id=12345,这些工具无法理解 JS 按钮,并且无法在表单中执行postor getor or click buttonor之类的操作submit,其只是如何从请求中读取数据。

  2. Mechnizeor robobrowseror MechnicalSoup:用于网页浏览和 cookie 处理、浏览器历史记录的出色工具,我们可以将这些工具视为 and 的组合requestBeautifullSoup因此我们可以轻松地在页面 html 内容中制作getpost和导航,例如,这些技术不是真正的浏览器,所以它不能执行和理解 JS,不能发送异步请求,不能移动滚动条,不能导出选定的数据表格......所以这些工具不足以发出复杂​​的请求。submit in formBeautifullSoup

  3. Selenium: 是一个强大的工具和一个真正的浏览器,我们可以随心所欲地获取数据,我们可以制作getand post, search, submit, selecting,move scroolbar它就像我们使用任何导航器一样使用,Selemenium什么都不用是不可能的,我们可以使用带有GUI的真正浏览器或我们可以option = 'headless'用于服务器环境。

吹我解释我们如何submit在一个表格JS buttonserver environment一步一步地点击。

A. 为服务器环境安装 webdriver: 打开终端:

sudo apt install chromium-chromedriver
sudo pip install selenium

如果您想使用 webdriver 进行 GUI 界面下载,请从 https://chromedriver.chromium.org/downloads

B. Python 2.7 中的示例,它也适用于 Python 3,只需编辑打印行

from selenium.webdriver.chrome.options import Options
from selenium import webdriver

options = Options()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
# define downlaoded directory
options.add_experimental_option("prefs", {
   "download.default_directory": "/tmp/",
   "download.prompt_for_download": False,
    })

browser = webdriver.Chrome(chrome_options=options)  # see edit for recent code change.


USERNAME = 'mail'
PASSWORD = 'password'

browser.get('http://www.example.com')
print browser.title

user_input = browser.find_element_by_id('mail_input')
user_input.send_keys(USERNAME)

pass_input = browser.find_element_by_id('pass_input')
pass_input.send_keys(PASSWORD)


login_button = browser.find_element_by_id("btn_123")
login_button.click()

csv_button = browser.find_element_by_id("btn45875465")
csv_button.click()

browser.close() # to close current page or you can use too `browser.quit()` to destroy the hole of webdriver instance

# Check if the file was downloaded completely and seccessfully
file_path = '/tmp/file_name'

while not os.path.exists(file_path):
    time.sleep(1)

if os.path.isfile(file_path):
    print 'The file was downloaded completely and seccessfully'

推荐阅读