Запросы Python и cURL никогда не возвращают ответ

Я пытаюсь очистить веб-сайт NSE для конкретной компании, на Python. Я пытаюсь это сделать, используя библиотеку requests и соответствующий метод get(). Это должно вернуть файл .html, который я затем смогу использовать для дальнейшей обработки с помощью Beautiful Soup 4.

url = 'https://www.nseindia.com/get-quotes/equity?symbol=20MICRONS'

response = requests.get(url)

Однако это не дает ответа даже через несколько минут, а вместо этого приводит к сбою моей системы. Судя по вопросу, Запросы GET Python требуют много времени для ответа на некоторые запросы,

Сервер может разрешать только определенные строки пользовательского агента.

Я добавил строку пользовательского агента в headers запроса следующим образом:

url = 'https://www.nseindia.com/get-quotes/equity?symbol=20MICRONS'
headers = {
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
}

response = requests.get(url, headers=headers)

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

IPv6 не работает, но IPv4 работает

На самом деле это было так: когда я попытался запустить его в режиме IPv6, я получил ошибку.

$ curl --ipv6 -v 'https://www.nseindia.com/get-quotes/equity?symbol=20MICRONS'          
* Could not resolve host: www.nseindia.com
* Closing connection
curl: (6) Could not resolve host: www.nseindia.com

Но и в этом случае режим IPv4 оказался не намного лучше.

$ curl --ipv4 'https://www.nseindia.com/get-quotes/equity?symbol=20MICRONS' # -v removed to focus on the error
curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)

Очевидно, что сайт также не поддерживает HTTP/"# м

2, и он, наконец, запустился при запуске с режимом HTTP/1.1.

curl --ipv4 -v 'https://www.nseindia.com/get-quotes/equity?symbol=20MICRONS' --http1.1
* Host www.nseindia.com:443 was resolved.
* IPv6: (none)
* IPv4: 184.29.25.143
*   Trying 184.29.25.143:443...
* Connected to www.nseindia.com (184.29.25.143) port 443
* ALPN: curl offers http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / x25519 / RSASSA-PSS
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: C=IN; ST=Maharashtra; L=Mumbai; O=National Stock Exchange of India Ltd.; CN=www.nseindia.com
*  start date: May 28 00:00:00 2024 GMT
*  expire date: May 22 23:59:59 2025 GMT
*  subjectAltName: host "www.nseindia.com" matched cert's "www.nseindia.com"
*  issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=GeoTrust RSA CA 2018
*  SSL certificate verify ok.
*   Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 1: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 2: Public key type RSA (2048/112 Bits/secBits), signed using sha1WithRSAEncryption
* using HTTP/1.x
> GET /get-quotes/equity?symbol=20MICRONS HTTP/1.1
> Host: www.nseindia.com
> User-Agent: curl/8.8.0
> Accept: */*
> 
* Request completely sent off
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing

Однако запрос cURL все еще не завершен. Затем я просмотрел вопросы, касающиеся самого веб-сайта NSE India , и нашел вопрос: Запросы Python получают код ответа 401 для веб-сайта NSE India,

Чтобы получить доступ к сайту NSE (api) несколько раз, затем установите файлы cookie в каждом последующем запросе.

по сути рекомендую добавить cookies к запросу.

baseurl = 'https://www.nseindia.com/'
url = 'https://www.nseindia.com/get-quotes/equity?symbol=20MICRONS'
headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
    'accept-language': 'en,gu;q=0.9,hi;q=0.8',
    'accept-encoding': 'gzip, deflate, br'
}

session = requests.Session()
request = session.get(baseurl, headers=headers, timeout=5)
cookies = dict(request.cookies)
response = session.get(url, headers=headers, timeout=5, cookies=cookies)

Это решение по-прежнему сталкивалось с той же проблемой: запрос просто никогда не завершался. Этот вопрос был задан и дан ответ для NSE India API , и вполне понятно, что он не работает. Я также проверил, добавив заголовок Accept согласно комментарию @GTK,

вам нужен заголовок accept [...]

url = 'https://www.nseindia.com/get-quotes/equity?symbol=20MICRONS'
headers = {
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
    "Accept": "text/html"
}

response = requests.get(url, headers=headers)

К сожалению, это не влияет на проблему, возможно, потому, что для заголовка Accept уже установлено значение */*, что позволяет использовать любой тип MIME.

Как мне поступить в этой ситуации и почему это происходит. Действительно ли запрос настолько медленный или произошла какая-то ошибка?

вам нужен заголовок accept и user-agent.

GTK 26.06.2024 22:54

@GTK У запросов уже нет заголовка accept, включая text/html?

Shirsak 26.06.2024 23:27

это ваш пользовательский агент (Linux), попробуйте этот пользовательский агент Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36

GTK 26.06.2024 23:49

возможно, сначала используйте DevTools в Chrome/Firefox, чтобы увидеть, какие заголовки отправляет реальный веб-браузер, и начните со всех заголовков из браузера. А позже вы сможете проверить, какие заголовки можно пропустить. Возможно, ему также придется вести себя как настоящий пользователь и сначала посетить главную страницу, чтобы получить файлы cookie, а затем использовать файлы cookie на следующих страницах. Но я думаю, что может быть и другая проблема - эта страница использует JavaScript для добавления некоторых элементов в HTML - поэтому, если вы планируете получать данные из HTML, тогда запросы могут быть бесполезны, и может потребоваться использование Selenium для управления реальным веб-браузером, который может запускать JavaScript.

furas 27.06.2024 01:26

Кстати: когда я использую DevTools (вкладка Network), чтобы увидеть запрос, он показывает мне, что этот сервер использует HTTP/2. Насколько я знаю, requests не поддерживает HTTP/2 — и его нужно будет использовать httpx. Но по-прежнему реальной проблемой является JavaScript, и даже httpx не может ее решить.

furas 27.06.2024 01:32
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Мне удалось получить ответ от сервера с другим заголовком User-Agent (скорее всего, сервер занес в черный список некоторые конкретные пользовательские агенты):

import requests

url = "https://www.nseindia.com/get-quotes/equity?symbol=20MICRONS"

headers = {
    "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:126.0) Gecko/20100101 Firefox/126.0",
}

response = requests.get(url, headers=headers)

print(response.text)

Распечатки:

<!DOCTYPE html>

<html lang = "en">

  <head>

    <meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />

<meta http-equiv = "Content-Type" content = "text/html; charset=ISO-8859-1">

<meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" />

<meta name = "viewport" content = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />

<title>

    20 Microns Limited Share Price Today, Stock Price, Live NSE News, Quotes, Tips – NSE India

</title>

...

Этот заголовок User-Agent работал, но откуда я мог знать, что это необходимое значение заголовка?

Shirsak 27.06.2024 18:00

@Shirsak Нет документации - это метод проб и ошибок.

Andrej Kesely 27.06.2024 19:33

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