无法使用 Python 从网站下载文件
Can't download a file from a website using Python
我是一个网络抓取新手,我在使用所有可以想到的 .get 方法从网站下载一些 excel 文件时遇到了问题。我已经能够轻松解析 HTML 以获取页面上每个 link 的 URL,但我没有足够的经验来理解为什么我无法下载文件(cookie、会话、等等,不知道)。
这是网站:
如果向下滚动,您会找到 5 个 excel 文件 link,其中 none 我可以下载。 (只需搜索 id="AutoDownload"
当我尝试使用 requests .get 方法并使用
保存文件时
import requests
requests.Session()
res = requests.get(url).content
with open(filename) as f:
f.write(res.content)
我得到一个错误,提示 res 是一个字节对象,当我将 res 视为一个变量时,输出是:
b'<html><head><title>Request Rejected</title></head><body>The requested URL was rejected.
Please consult with your administrator.<br><br>Your support ID is: 11190392837244519859</body></html>
已经尝试了一段时间,非常感谢任何帮助。非常感谢。
如果您没有足够的经验在 HTTP 请求中手动设置所有正确的参数以避免出现“请求被拒绝”错误(就我而言,我做不到),我会建议您使用更高级别的方法,例如 Selenium。
Selenium 可以自动执行安装在您计算机上的浏览器执行的操作,例如下载文件(因此它用于自动测试网络应用程序以及进行网络抓取)。想法是浏览器生成的 HTTP 请求会比你手写的更好。
Here 是一个使用 Selenium 来完成您尝试做的事情的教程。
为了下载文件,您需要在 python 请求的 header 中设置“User-Agent”字段。这可以通过将字典传递给 get 函数来完成:
file = session.get(url,headers=my_headers)
显然,该主机不响应来自 python 的具有以下 User-Agent 的请求:
'User-Agent': 'python-requests/2.24.0'
考虑到这一点,如果您在请求的 header 中为该字段传递另一个值,例如来自 Firefox 的值(见下文),主机会认为该请求来自 Firefox 用户,并且将以实际文件响应。
这里是代码的完整版本:
import requests
my_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
'Accept-Encoding': 'gzip, deflate',
'Accept': '*/*',
'Connection': 'keep-alive'
}
session = requests.session()
file = session.get(url, headers=my_headers)
with open(filename, 'wb') as f:
f.write(file.content)
最新的 Firefox 用户代理对我有用,但您可以为该字段找到更多可能的值 here。
所以我终于想出了一个只使用 requests
和标准 Python HTML 解析器的解决方案。
根据我的发现,Request rejected
错误通常很难追溯到确切的原因。在那种情况下,这是由于 HTTP 请求中缺少用户代理。
import requests
from html.parser import HTMLParser
# Custom parser to retrieve the links
link_urls = []
class AutoDownloadLinksHTMLParser(HTMLParser):
def handle_starttag(self, tag, attrs):
if(tag == 'a' and [attr for attr in attrs if attr == ('id', 'AutoDownload')]):
href = [attr[1] for attr in attrs if attr[0] == 'href'][0]
link_urls.append(href)
# Get the links to the files
url = 'https://mlcu.org.eg/ar/3118/%D9%82%D9%88%D8%A7%D8%A6%D9%85-%D9%85%D8%AC%D9%84%D8%B3-%D8%A7%D9%84%D8%A7%D9%85%D9%86-%D8%B0%D8%A7%D8%AA-%D8%A7%D9%84%D8%B5%D9%84%D8%A9'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'}
links_page = requests.get(url, headers=headers)
AutoDownloadLinksHTMLParser().feed(links_page.content.decode('utf-8'))
# Download the files
host = 'https://mlcu.org.eg'
for i, link_url in enumerate(link_urls):
file_content = requests.get(host + link_urls[i], headers = headers).content
with open('file' + str(i) + '.xls', 'wb+') as f:
f.write(file_content)
我是一个网络抓取新手,我在使用所有可以想到的 .get 方法从网站下载一些 excel 文件时遇到了问题。我已经能够轻松解析 HTML 以获取页面上每个 link 的 URL,但我没有足够的经验来理解为什么我无法下载文件(cookie、会话、等等,不知道)。
这是网站:
如果向下滚动,您会找到 5 个 excel 文件 link,其中 none 我可以下载。 (只需搜索 id="AutoDownload"
当我尝试使用 requests .get 方法并使用
保存文件时import requests
requests.Session()
res = requests.get(url).content
with open(filename) as f:
f.write(res.content)
我得到一个错误,提示 res 是一个字节对象,当我将 res 视为一个变量时,输出是:
b'<html><head><title>Request Rejected</title></head><body>The requested URL was rejected.
Please consult with your administrator.<br><br>Your support ID is: 11190392837244519859</body></html>
已经尝试了一段时间,非常感谢任何帮助。非常感谢。
如果您没有足够的经验在 HTTP 请求中手动设置所有正确的参数以避免出现“请求被拒绝”错误(就我而言,我做不到),我会建议您使用更高级别的方法,例如 Selenium。
Selenium 可以自动执行安装在您计算机上的浏览器执行的操作,例如下载文件(因此它用于自动测试网络应用程序以及进行网络抓取)。想法是浏览器生成的 HTTP 请求会比你手写的更好。
Here 是一个使用 Selenium 来完成您尝试做的事情的教程。
为了下载文件,您需要在 python 请求的 header 中设置“User-Agent”字段。这可以通过将字典传递给 get 函数来完成:
file = session.get(url,headers=my_headers)
显然,该主机不响应来自 python 的具有以下 User-Agent 的请求:
'User-Agent': 'python-requests/2.24.0'
考虑到这一点,如果您在请求的 header 中为该字段传递另一个值,例如来自 Firefox 的值(见下文),主机会认为该请求来自 Firefox 用户,并且将以实际文件响应。
这里是代码的完整版本:
import requests
my_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
'Accept-Encoding': 'gzip, deflate',
'Accept': '*/*',
'Connection': 'keep-alive'
}
session = requests.session()
file = session.get(url, headers=my_headers)
with open(filename, 'wb') as f:
f.write(file.content)
最新的 Firefox 用户代理对我有用,但您可以为该字段找到更多可能的值 here。
所以我终于想出了一个只使用 requests
和标准 Python HTML 解析器的解决方案。
根据我的发现,Request rejected
错误通常很难追溯到确切的原因。在那种情况下,这是由于 HTTP 请求中缺少用户代理。
import requests
from html.parser import HTMLParser
# Custom parser to retrieve the links
link_urls = []
class AutoDownloadLinksHTMLParser(HTMLParser):
def handle_starttag(self, tag, attrs):
if(tag == 'a' and [attr for attr in attrs if attr == ('id', 'AutoDownload')]):
href = [attr[1] for attr in attrs if attr[0] == 'href'][0]
link_urls.append(href)
# Get the links to the files
url = 'https://mlcu.org.eg/ar/3118/%D9%82%D9%88%D8%A7%D8%A6%D9%85-%D9%85%D8%AC%D9%84%D8%B3-%D8%A7%D9%84%D8%A7%D9%85%D9%86-%D8%B0%D8%A7%D8%AA-%D8%A7%D9%84%D8%B5%D9%84%D8%A9'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'}
links_page = requests.get(url, headers=headers)
AutoDownloadLinksHTMLParser().feed(links_page.content.decode('utf-8'))
# Download the files
host = 'https://mlcu.org.eg'
for i, link_url in enumerate(link_urls):
file_content = requests.get(host + link_urls[i], headers = headers).content
with open('file' + str(i) + '.xls', 'wb+') as f:
f.write(file_content)