Загрузка PDF как пустая по ссылке даже после предоставления заголовков в запросе

Ответ на запрос 200, но файл все равно загружается как пустой. Пожалуйста, помогите решить эту задачу.

import requests
HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}

r = requests.get(link, stream=True, headers=HEADERS)
with open(output_filename, 'wb') as f:
    f.write(r.content)

PDF-файл отображается на этой странице, но ваш URL-адрес не является прямой гиперссылкой на PDF-документ.

DarkKnight 14.07.2023 15:34

@DarkKnight тогда как это сделать

ninja_haze_developer2484 14.07.2023 15:36

Вам нужно выяснить, где находятся PDF-файлы. Изучение HTML/JavaScript может помочь вам

DarkKnight 14.07.2023 15:49

Пожалуйста, уточните вашу конкретную проблему или предоставьте дополнительную информацию, чтобы выделить именно то, что вам нужно. Как сейчас написано, трудно точно сказать, о чем вы спрашиваете.

Community 14.07.2023 16:34

@ninja_haze_developer2484 Почему ты удалил ссылку?

Constantin Hong 16.07.2023 11:24
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На странице html есть форма. Вы можете отправить эту форму или получить ключ/закодированную строку и отправить запрос на pdf с новой ссылкой/url.

import requests
import re
from bs4 import BeautifulSoup as bs

url = "url1"

# get key from html page -> <form> -> <script> {encodedString = dfsfsdfs}</script>
with requests.Session() as session:
    res = session.get(url)
soup = bs(res.text, 'html.parser')
form = soup.select_one('form#SummaryForm > script', string=re.compile('encodedString'))

key = re.findall(r"encodedString = '([^']*)'", form.text)[0]
# fid from url string
fid = re.findall(r'fundid=(\d+)', url)[0]   

# For the download link, searched for xhr, by going to inspect devtools, -> Network tabs, and filter by fetch/xhr.
link = f'new_url_to_pdf?key = {key}&fid = {fid}'
output_filename = 'file.pdf'
r = requests.get(link)
with open(output_filename, 'wb') as f:
    f.write(r.content)

Этому есть альтернатива — Selenium и Requests-html. Поскольку вам нужно очень меньше взаимодействия с браузером, вы можете попробовать запросы-html.

from requests_html import HTMLSession


url = 'url2'
script = """
window.addEventListener('load', function () {
    iframe = document.selector('iframe:not([style* = "display: none"])')[0].click();
    e = $.Event("keydown");
    e.which = 83; // S
    e.ctrlKey = true; // CTRL
    $(document).trigger(e);
})
"""

session = HTMLSession()
res = session.get(url)
res.html.render(sleep=2, keep_page=True, script=script)

Он автоматически загрузит веб-драйвер при первом запуске кода. Таким образом, первый запуск может занять немного времени, следующий запуск будет быстрее.

Редактировать 2:
requests-html не работает из-за наличия iframe

СПАСИБО @daniel за спасение!

ninja_haze_developer2484 14.07.2023 21:56

как вы получаете данные ссылки

ninja_haze_developer2484 14.07.2023 21:59

замените (\w+) на (.+) в key. изначально он показывал только буквенно-цифровое значение, я предполагал, что это так.

Daniel Sabrel 14.07.2023 21:59

для ссылки для скачивания, искал xhr, зайдя в devtools, -> Сетевые краны, фильтровать по fetch/xhr. Там вы увидите что-то вроде pro?key=I9.... Нажмите на него и сбоку выберите Заголовки

Daniel Sabrel 14.07.2023 22:05

Возможно, вам придется нажать F5 или Ctrl+R, если вы уже загрузили страницу.

Daniel Sabrel 14.07.2023 22:11

как написать код, чтобы он работал для всех ссылок

ninja_haze_developer2484 14.07.2023 22:30

на обоих вышеуказанных сайтах вы можете найти ссылку запроса, как я упоминал выше. для ссылки потребуется некоторый ключ, который вы можете найти в html или сценариях. Что касается кода, который будет работать на любом/каждом сайте, то его не существует. Каждый сайт создается по-своему. Таким образом, всегда будут некоторые различия, чтобы очистить их.

Daniel Sabrel 14.07.2023 22:41

Можем ли мы написать некоторую логику на стороне html, чтобы автоматически получать эти ссылки. Просто спросите, я знаю, что ваши усилия достойны похвалы.

ninja_haze_developer2484 14.07.2023 22:45

Я не понял, что вы имеете в виду, когда пишете логику на стороне html.

Daniel Sabrel 14.07.2023 22:51

Используя requests+bs4, вам нужно будет получить url-of-pdf через xhr/fetch для каждого сайта (не для каждого URL). Но для ваших URL-адресов, поскольку сайты кажутся довольно похожими с кнопкой загрузки, вы можете использовать Selenium, который имеет функцию щелчка. Итак, вы пишете код для передачи URL-адреса и нажимаете кнопку с надписью «Загрузить», и все готово.

Daniel Sabrel 14.07.2023 22:57

@DanielSabrel У меня не получилось с регулярным выражением ключа. Моя довольно грубая key = re.findall(r"encodedString = '([^']*)'?", form.text)[0]. Могу я дать совет, пожалуйста?

Constantin Hong 14.07.2023 23:44

@ConstantinHong да, ты прав. Не проверял это.

Daniel Sabrel 14.07.2023 23:54

res.html.render(sleep=2, keep_page=True, script=script) -> сбой на этом этапе

ninja_haze_developer2484 15.07.2023 13:55

Другие вопросы по теме