CoderCastrov logo
CoderCastrov
Nasdaq

Парсинг Nasdaq

Парсинг Nasdaq
просмотров
8 мин чтение
#Nasdaq

Каждый знает, что такое Nasdaq. В основном, это рынок для покупки и продажи акций. Это была первая онлайн-платформа для торговли акциями во всем мире. Но зачем парсить его? Ну, Nasdaq - это сайт с богатыми данными, и если у вас есть такие данные, то вы можете сделать следующее:

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

Так что в этом блоге нашей целью является парсинг информации о акциях Tesla. Мы будем использовать Python для создания этого парсера. В дальнейшем в этом блоге мы также создадим оповещение по электронной почте, через которое вы сможете отправить себе электронное письмо, когда акция достигнет целевой цены.

Приступим к кодированию!

Я предполагаю, что вы уже установили python на свой компьютер. Затем мы создадим папку и установим все необходимые библиотеки в ней.

>> mkdir nasdaq
>> pip install selenium
>> pip install beautifulsoup4

Мы установили Selenium и BeautifulSoup. Selenium - это инструмент для автоматизации браузера, он будет использоваться для загрузки целевого URL-адреса NASDAQ в реальном браузере Chrome. BeautifulSoup, также известный как BS4, будет использоваться для извлечения чистых данных из необработанного HTML, возвращаемого Selenium.

Мы могли бы использовать библиотеку requests, но поскольку NASDAQ загружает все с помощью JavaScript, обычный HTTP GET-запрос был бы бесполезен. Если вы хотите узнать больше о разнице в том, как веб-сайты загружают данные с помощью JavaScript и AJAX-запросов, прочтите парсинг Zillow для полной информации по этой теме.

Наш целевой URL будет этот, и мы извлечем следующие данные с этой страницы.

Я думаю, этого будет достаточно.

Я выделил данные, которые мы собираемся извлечь. Создайте файл на языке Python с любым именем и импортируйте все библиотеки.

from bs4 import BeautifulSoup
from selenium import webdriver
import time

Давайте сначала определим HTML-местоположение каждого из этих элементов, проанализировав их.

Имя хранится в теге span с классом «symbol-page-header__name».

Цена продажи также хранится в теге span с классом «summary-data__table-body».

Коэффициент P/E и дата выплаты дивидендов являются частью второго элемента tbody таблицы.

Цель на 1 год является частью первого элемента tbody таблицы.

Наконец, у нас есть точные местоположения каждого из этих элементов. Давайте извлечем их пошагово.

from selenium.webdriver.common.keys import KeysPATH = 'C:\Program Files (x86)\chromedriver.exe'l=list()
obj={}target_url = "[https://www.nasdaq.com/market-activity/stocks/tsla](https://www.nasdaq.com/market-activity/stocks/tsla)"driver=webdriver.Chrome(PATH)driver.get(target_url)
html = driver.find_element_by_tag_name('html')
html.send_keys(Keys.END)
time.sleep(2)
resp = driver.page_source
driver.close()

Мы также импортировали метод «Keys» из Selenium, чтобы прокрутить страницу вниз и загрузить каждый элемент страницы. Затем мы определили местоположение нашего браузера Chromium и вместе с этим мы также определили наш целевой URL.

Затем мы извлекаем все необработанный HTML с помощью веб-драйвера Selenium, и после получения всего HTML-кода мы закрываем драйвер с помощью функции .close().

soup=BeautifulSoup(resp,'html.parser')try:
    obj["name"]=soup.find("span",{"class":"symbol-page-header__name"}).text
except:
    obj["name"]=Nonetry:
    obj["askPrice"]=soup.find("span",{"class":"symbol-page-header__pricing-ask"}).text
except:
    obj["askPrice"]=Nonetables = soup.find("table",{"class":"summary-data__table"}).find_all("tbody",{"class":"summary-data__table-body"})
print(tables)
table1 = tables[0]
table2=tables[1]try:
    obj["P/E Ratio"]=table2.find_all("tr",{"class":"summary-data__row"})[0].find("td",{"class":"summary-data__cell"}).text
except:
    obj["P/E Ratio"]=Nonetry:
    obj["1-year budget"]=table1.find_all("tr",{"class":"summary-data__row"})[3].find("td",{"class":"summary-data__cell"}).text
except:
    obj["1-year budget"]=Nonetry:
    obj["Dividend"]=table2.find_all("tr",{"class":"summary-data__row"})[7].find("td",{"class":"summary-data__cell"}).text
except:
    obj["Dividend"]=Nonel.append(obj)
obj={}print(l)

Затем, после закрытия браузера, мы создали дерево HTML с помощью BS4. Из этого дерева мы собираемся извлечь наши интересующие нас данные с помощью функции .find(). Мы собираемся использовать точно то же самое местоположение HTML, которое мы обнаружили выше.

Часть с таблицей может быть немного запутанной для вас. Позвольте мне объяснить это.

Сначала мы находим элемент таблицы с помощью .find(), а затем у нас есть .find_all(), чтобы найти оба элемента tbody. Первый элемент tbody содержит значение на 1 год, а другой содержит и дату выплаты дивидендов, и коэффициент P/E. Надеюсь, ваше недоразумение теперь прояснено.

После запуска этого кода вы получите все данные, которые мы искали, в виде массива.

from bs4 import BeautifulSoup
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys

PATH = 'C:\Program Files (x86)\chromedriver.exe'
l = list()
obj = {}

target_url = "https://www.nasdaq.com/market-activity/stocks/tsla"
driver = webdriver.Chrome(PATH)
driver.get(target_url)

html = driver.find_element_by_tag_name('html')
html.send_keys(Keys.END)
time.sleep(2)
resp = driver.page_source
driver.close()

soup = BeautifulSoup(resp, 'html.parser')

try:
    obj["name"] = soup.find("span", {"class": "symbol-page-header__name"}).text
except:
    obj["name"] = None

try:
    obj["askPrice"] = soup.find("span", {"class": "symbol-page-header__pricing-ask"}).text
except:
    obj["askPrice"] = None

tables = soup.find("table", {"class": "summary-data__table"}).find_all("tbody", {"class": "summary-data__table-body"})
print(tables)

table1 = tables[0]
table2 = tables[1]

try:
    obj["P/E Ratio"] = table2.find_all("tr", {"class": "summary-data__row"})[0].find("td", {"class": "summary-data__cell"}).text
except:
    obj["P/E Ratio"] = None

try:
    obj["1-year budget"] = table1.find_all("tr", {"class": "summary-data__row"})[3].find("td", {"class": "summary-data__cell"}).text
except:
    obj["1-year budget"] = None

try:
    obj["Dividend"] = table2.find_all("tr", {"class": "summary-data__row"})[7].find("td", {"class": "summary-data__cell"}).text
except:
    obj["Dividend"] = None

l.append(obj)
obj = {}

print(l)

Оповещение о цене акций Target

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

Мы будем использовать библиотеку python schedule, которая поможет вам запускать код в заданный интервал времени. Давайте разделим этот раздел на две части. В первой части мы будем запускать парсер каждые 15 минут, а во второй части мы отправим себе электронное письмо, когда цена достигнет целевого уровня.

Target Stock

Часть I — Запуск парсера каждые 24 часа

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

from bs4 import BeautifulSoup
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys
import schedule

PATH = 'C:\Program Files (x86)\chromedriver.exe'
l = list()
obj = {}

target_url = "https://www.nasdaq.com/market-activity/stocks/tsla"

def tracker():
    driver = webdriver.Chrome(PATH)
    driver.get(target_url)
    html = driver.find_element_by_tag_name('html')
    html.send_keys(Keys.END)
    time.sleep(2)
    resp = driver.page_source
    driver.close()
    
    soup = BeautifulSoup(resp, 'html.parser')
    
    try:
        obj["name"] = soup.find("span", {"class": "symbol-page-header__name"}).text
    except:
        obj["name"] = None
    
    try:
        obj["askPrice"] = soup.find("span", {"class": "symbol-page-header__pricing-ask"}).text
    except:
        obj["askPrice"] = None
    
    tables = soup.find("table", {"class": "summary-data__table"}).find_all("tbody", {"class": "summary-data__table-body"})
    print(tables)
    
    table1 = tables[0]
    table2 = tables[1]
    
    try:
        obj["P/E Ratio"] = table2.find_all("tr", {"class": "summary-data__row"})[0].find("td", {"class": "summary-data__cell"}).text
    except:
        obj["P/E Ratio"] = None
    
    try:
        obj["1-year budget"] = table1.find_all("tr", {"class": "summary-data__row"})[3].find("td", {"class": "summary-data__cell"}).text
    except:
        obj["1-year budget"] = None
    
    try:
        obj["Dividend"] = table2.find_all("tr", {"class": "summary-data__row"})[7].find("td", {"class": "summary-data__cell"}).text
    except:
        obj["Dividend"] = None
    
    l.append(obj)
    obj = {}
    
    print(l)

if __name__ == "__main__":
    schedule.every().minute.at(":15").do(tracker)
    
    while True:
        schedule.run_pending()

Здесь, внутри нашей main функции, мы использовали библиотеку schedule для запуска функции tracker каждые 15 минут. Теперь давайте отправим себе электронное письмо для оповещения о цене.

from bs4 import BeautifulSoup
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys
import schedule

PATH = 'C:\Program Files (x86)\chromedriver.exe'
l = list()
obj = {}

target_url = "https://www.nasdaq.com/market-activity/stocks/tsla"

def tracker():
    driver = webdriver.Chrome(PATH)
    driver.get(target_url)
    html = driver.find_element_by_tag_name('html')
    html.send_keys(Keys.END)
    time.sleep(2)
    resp = driver.page_source
    driver.close()
    soup = BeautifulSoup(resp, 'html.parser')
    
    try:
        obj["name"] = soup.find("span", {"class": "symbol-page-header__name"}).text
    except:
        obj["name"] = None
    
    try:
        obj["askPrice"] = soup.find("span", {"class": "symbol-page-header__pricing-ask"}).text
    except:
        obj["askPrice"] = None
    
    tables = soup.find("table", {"class": "summary-data__table"}).find_all("tbody", {"class": "summary-data__table-body"})
    print(tables)
    table1 = tables[0]
    table2 = tables[1]
    
    try:
        obj["P/E Ratio"] = table2.find_all("tr", {"class": "summary-data__row"})[0].find("td", {"class": "summary-data__cell"}).text
    except:
        obj["P/E Ratio"] = None
    
    try:
        obj["1-year budget"] = table1.find_all("tr", {"class": "summary-data__row"})[3].find("td", {"class": "summary-data__cell"}).text
    except:
        obj["1-year budget"] = None
    
    try:
        obj["Dividend"] = table2.find_all("tr", {"class": "summary-data__row"})[7].find("td", {"class": "summary-data__cell"}).text
    except:
        obj["Dividend"] = None
    
    if obj["askPrice"] >= 278:
        mail()
    
    l.append(obj)
    obj = {}
    print(l)

def mail():
    Msg = "Акции достигли вашей целевой цены, пора заработать немного денег."
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.ehlo()
    server.starttls()
    server.login("from@gmail.com", "xxxx")
    SUBJECT = "Уведомление о цене акций"
    message = 'From: from@gmail.com \nSubject: {}\n\n{}'.format(SUBJECT, Msg)
    server.sendmail("from@gmail.com", 'send_to@gmail.com', message)

if __name__ == "__main__":
    schedule.every().minute.at(":15").do(tracker)
    while True:
        schedule.run_pending()

Как парсить Nasdaq с помощью Scrapingdog

Nasdaq - очень популярный веб-сайт биржи с обширными данными, и многие люди регулярно парсят его. Как мы уже обсудили выше, для парсинга Nasdaq нельзя использовать обычные HTTP GET-запросы, поэтому нам понадобится поддержка безголового Chrome для парсинга, и если вы хотите делать это в масштабе, это требует больших ресурсов. Давайте посмотрим, как Scrapingdog может помочь вам в парсинге этого веб-сайта.

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

Давайте пошагово разберемся, как вы можете использовать Scrapingdog для парсинга Nasdaq без затрат на ресурсоемкую архитектуру. О, я почти забыл сказать вам, что для новых пользователей первые 1000 вызовов абсолютно бесплатны.

Сначала вам нужно зарегистрироваться!

from bs4 import BeautifulSoup
import schedule
import smtplib
import requests

PATH = 'C:\Program Files (x86)\chromedriver.exe'
l = list()
obj = {}

target_url = "[https://api.scrapingdog.com/scrape?api_key=YOUR-API-KEY&url=https://www.nasdaq.com/market-activity/stocks/tsla](https://api.scrapingdog.com/scrape?api_key=YOUR-API-KEY&url=https%3A%2F%2Fwww.nasdaq.com%2Fmarket-activity%2Fstocks%2Ftsla)"

def mail():
    attackMsg = "Цена акции достигла вашей целевой цены, пришло время заработать деньги."
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.ehlo()
    server.starttls()
    server.login("[from@gmail.com](mailto:from@gmail.com)", "xxxx")
    SUBJECT = "Оповещение о цене акции"
    message = 'From: [from@gmail.com](mailto:from@gmail.com) \nSubject: {}\n\n{}'.format(SUBJECT, attackMsg)
    server.sendmail("[from@gmail.com](mailto:from@gmail.com)", '[send_to@gmail.com](mailto:send_to@gmail.com)', message)

def tracker():
    resp = requests.get(target_url).text   
    soup = BeautifulSoup(resp, 'html.parser')

    try:
        obj["name"] = soup.find("span", {"class": "symbol-page-header__name"}).text
    except:
        obj["name"] = None

    try:
        obj["askPrice"] = soup.find("span", {"class": "symbol-page-header__pricing-ask"}).text
    except:
        obj["askPrice"] = None

    tables = soup.find("table", {"class": "summary-data__table"}).find_all("tbody", {"class": "summary-data__table-body"})
    print(tables)
    table1 = tables[0]
    table2 = tables[1]

    try:
        obj["P/E Ratio"] = table2.find_all("tr", {"class": "summary-data__row"})[0].find("td", {"class": "summary-data__cell"}).text
    except:
        obj["P/E Ratio"] = None

    try:
        obj["1-year budget"] = table1.find_all("tr", {"class": "summary-data__row"})[3].find("td", {"class": "summary-data__cell"}).text
    except:
        obj["1-year budget"] = None

    try:
        obj["Dividend"] = table2.find_all("tr", {"class": "summary-data__row"})[7].find("td", {"class": "summary-data__cell"}).text
    except:
        obj["Dividend"] = None

    if obj["askPrice"] == 278:
        mail()

    l.append(obj)
    obj = {}
    print(l)

if __name__ == "__main__":
    schedule.every().minute.at(":15").do(tracker)
    while True:
        schedule.run_pending()

Заключение

Мы можем создать систему оповещения о ценах для любого веб-сайта, например, цены на авиабилеты с сайтов, таких как Expedia, цены на товары с Amazon и т. д. С помощью Python вы можете создать эти парсеры с минимальными усилиями. Однако, очевидно, есть некоторые ограничения при парсинге этих веб-сайтов без использования Web Scraping API.

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

Дополнительные ресурсы