首页 > 解决方案 > 如果文件未向公众开放,则从网站上下载的 Python 3 Mechanizesoup 文件损坏

问题描述

如果文件对公众开放,我的 python 代码就可以工作。它可以下载任何文件并在目标系统上运行。如果文件受主机保护(非公开),则下载的文件已损坏。深入调查我发现它是主页的html内容而不是文件内容。

最初我以为这只是与pdf有关,直到我使用“代码”应用程序打开输出pdf并发现它实际上是主页的htm。

我使用 urllib 和 Mechanizesoup 登录到该站点。我可以告诉响应 htm 实际上是登录页面之后的主页。我尝试使用 cookie 和 url base64 授权。一样的症状。

我在 Internet 上看到很多关于损坏的下载文件的讨论。但是,如果我使用真正的浏览器,下载就可以了。我无法手动下载,因为我有数百个文件要备份。Python 是我知道如何自动化这种过程的唯一方法。

我需要帮助。

这是代码。网站和一些内容被修改以保护无辜者。

__author__ = 'it@lsyc.com'
# Alex 2021-04-23, initial coding

import urllib
import urllib.request
import base64
# from base64 import b64encode

import json
import re
import os
import datetime
from io import BytesIO 
import mechanicalsoup # Don’t forget to import the new module
from bs4 import BeautifulSoup

## These are fake url, user and passwords. Real site exists
WA_URL = "https://hosted.services.org"
LOGIN_URL = "https://hosted.services.org/Sys/Login"
LOGIN = "alex@gmail.com"
PASSWORD = "Crazy1991#$"

# LOGIN:PASSWORD = alex@gmail.com:Crazy1991#$
# following encoded with base64
auth_header = "YWxleGNvMzhAZ21haWwuY29tOkthaXplbjE5OTEjJA=="


## Try to use cookies, no difference
def save_cookies(browser):
    return browser.session.cookies.get_dict()

def load_cookies(browser, cookies):
    from requests.utils import cookiejar_from_dict
    browser.session.cookies = cookiejar_from_dict(cookies)


## url-A works because it is public access
url='https://hosted.services.org/resources/Documents/Reciprocal%20List%202018.pdf'

# url-B corrupts because it's restricted but not admin
# url='https://hosted.services.org/resources/Documents/IT%20Security%20and%20Web%20Terms%20and%20Conditions.pdf'


## This proc uses mechanizesoup
browser = mechanicalsoup.StatefulBrowser()
browser.open(WA_URL) # WA site

cookies = save_cookies(browser) # save and reload the cookie
load_cookies(browser, cookies)

browser.select_form('form[action="https://hosted.services.org/Sys/Login"]') # WA login page

# browser.get_current_form().print_summary() # print form inputs
browser.get_current_form().set_input({"email": LOGIN, "password": PASSWORD})
response = browser.submit_selected() # hit the submit button

# browser.add_header("Authorization", 'Basic ' + auth_header)
response = browser.open(url, headers={'Authorization': 'Basic %s' %  auth_header})

with open('WA_Copy.pdf', 'wb') as f:
    f.write(response.content)

browser.close()

标签: pythonpython-3.xurllibmechanize-python

解决方案


推荐阅读