#python #parsing #beautifulsoup #urllib
#python #синтаксический анализ #beautifulsoup #urllib
Вопрос:
Я новичок в Python и пытаюсь создать средство поиска Google с целью получения цен на акции, но я запускаю свой код ниже, и я не получаю никаких результатов, вместо этого я получаю форматирование страницы HTML.
import urllib.request
from bs4 import BeautifulSoup
import requests
url = 'https://www.google.com/webhp?sourceid=chrome-instantamp;ion=1amp;espv=2amp;ie=UTF-8#q=uwti'
response = requests.get(url)
html = response.content
soup = BeautifulSoup(html, "html.parser")
print(soup.prettify())
Я упускаю что-то очень простое, пожалуйста, дайте мне несколько советов по этому поводу. Я пытаюсь извлечь текущую стоимость акций.Как мне извлечь это значение из прикрепленного изображения?
Комментарии:
1. Похоже, что он получает цену и отображает ее динамически, вероятно, с использованием Javascript, поэтому он не отображается в HTML, который вы получаете от BeautifulSoup. Я думаю, вам нужно будет использовать другой подход. Есть много хороших вариантов Python для загрузки биржевых данных из Yahoo или Google, попробуйте изучить их.
2. @jeffcarey, он находится в исходном коде, если запрос выполнен правильно, Javascript не задействован.
Ответ №1:
Он находится в исходном коде, когда вы щелкаете правой кнопкой мыши и выбираете view-source в своем браузере. Вам просто нужно немного изменить URL-адрес и передать user-agent, чтобы он соответствовал тому, что вы видите там, используя запросы:
In [2]: from bs4 import BeautifulSoup
...: import requests
...:
...: url = 'https://www.google.com/search?q=uwtiamp;rct=j'
...: response = requests.get(url, headers={
...: "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (K
...: HTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"})
...: html = response.content
...:
...: soup = BeautifulSoup(html, "html.parser")
...: print(soup.select_one("span._Rnb.fmob_pr.fac-l").text)
...:
27.51
soup.find("span", class_="_Rnb fmob_pr fac-l").text
также будет работать и является правильным способом поиска тега с использованием классов css с помощью find или find_all
Вы можете видеть в Chrome, когда используете https://www.google.com/webhp?sourceid=chrome-instantamp;ion=1amp;espv=2amp;ie=UTF-8#q=uwti , есть перенаправление на https://www.google.com/search ?q = uwtiamp; rct = j:
Комментарии:
1. Падрайк, не могли бы вы дать мне несколько советов о том, как установить / найти подробную информацию о заголовках, которые вы упомянули в request.get
2. @Fenomatik, когда вы вводите google.com / … вы можете видеть, как это становится google.com/search ? q = uwtiamp; rct = j на ваш взгляд, если вы посмотрите запрос в Chrome tools, вы увидите, что все это происходит. Отправка пользовательского агента довольно стандартна и часто требуется при очистке сайта.
3. Я пытался использовать инструменты разработчика в Chrome, но я не смог найти никаких запросов GET, как вы нашли? в основном были запросы POST. Есть идеи, что я делаю не так?
4. Он определенно есть, убедитесь, что вы проверяете вкладку XHR, и вы делаете запрос после открытия инструментов.
Ответ №2:
- Добавьте
user-agent
в свой запрос, чтобы Google рассматривал ваш запрос как реальный визит пользователя, потому что по умолчаниюrequests
user-agent
используется python-requests, и Google понимает это и блокирует запросы, поэтому вы получаете другой HTML с какой-то ошибкой. Список пользовательских агентов. Проверьте, что у васuser-agent
. - Используйте расширение SelectorGadget для Chrome, чтобы быстро находить и захватывать
CSS
селекторы, нажимая на нужный элемент в вашем браузере.CSS
ссылки на селекторы. - Используйте извлеченный
CSS
селектор с помощью.select_one()
bs4
метода для получения данных.
Код и пример в онлайн-среде разработки:
from bs4 import BeautifulSoup
import requests, lxml
headers = {
'User-agent':
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582"
}
html = requests.get('https://www.google.com/search?q=spgsclp', headers=headers)
soup = BeautifulSoup(html.text, 'lxml')
current_stock_price = soup.select_one('.wT3VGc').text
print(current_stock_price)
# 108,52
Кроме того, вы можете сделать то же самое, используя Google Direct Answer Box API из SerpApi. Это платный API с бесплатным планом.
Самое большое отличие в вашем случае заключается в том, что вам не нужно выяснять, почему что-то не работает, и выяснять, как очистить эти данные. Процесс получения данных намного понятнее.
Код для интеграции:
from serpapi import GoogleSearch
params = {
"api_key": "YOUR_API_KEY",
"engine": "google",
"q": "spgsclp",
}
search = GoogleSearch(params)
results = search.get_dict()
current_stock_price = results['answer_box']['price']
print(current_stock_price)
# 108,52
Отказ от ответственности, я работаю в SerpApi.
Комментарии:
1. Лучше использовать новый user-agent. Google блокирует старые пользовательские агенты намного раньше. Смотрите user-agent.top для получения свежего списка
2. @MikhailYevchenko Спасибо, что упомянули об этом 👍 Есть также веб — сайт whatismybrowser, который показывает ваш текущий пользовательский агент. Или еще лучше использовать библиотеку, которая обновляет их автоматически.
Ответ №3:
Ознакомьтесь с Beautiful Soup's
документацией о том, как выбирать элементы HTML-документа, который вы только что проанализировали, вы могли бы попробовать что-то вроде:
soup.findAll("span", ['_Rnb', 'fmob_pr, 'fac-l'])
Вышеупомянутый метод найдет элемент span, который реализует классы в списке.
К вашему сведению: цена акций не извлекается при первоначальном запросе, насколько я вижу, используйте Inspect Element
функцию вашего браузера для захвата отправленных запросов, из того, что я вижу, есть запрос на URL https://www.google.gr/async/finance_price_updates
. Возможно, это используется для получения цены на акции, посмотрите, можете ли вы отправлять запросы к нему напрямую, а не извлекать весь HTML.
Ответ №4:
google не даст вам очистить его, поэтому вам придется использовать какой-либо API или просто сменить сайт акций.
import urllib
from bs4 import BeautifulSoup
url = 'siteurl'
response = urllib.urlopen(url)
soup = BeautifulSoup(response, "html.parser")
print(soup.findAll("div", { "class" : 'classname' }))
вы можете использовать этот код, просто изменив ‘siteurl’ и ‘classname’ (которые вам нужно очистить)