Получение данных от <tbody>с использованием запросов и beautifulsoup4 - PullRequest
0 голосов
/ 28 мая 2018

Чтобы лучше узнать, используя beautifulsoup4, я пытаюсь получить некоторые данные из https://semlar.com/rivenprices/artax (конечно, я использую эти данные ТОЛЬКО в учебных целях, чтобы избежать любых возможных юридических проблем. Все данныеПубликация здесь доступна для всех, кто использует браузерную функцию «inspect».

Этот сайт показывает средние цены на специальные моды в игре под названием Warframe, но это не главное.Я хотел бы написать приложение, которое берет имя мода (например, Artax, Lanka и т. Д.) От пользователя и печатает значения «Avg Price» и «Dispo».

Вот ссылка на небольшую частьиз таблицы я хотел бы получить данные: https://imggmi.com/full/2018/5/28/daa550ff5f042bb80ab0ecdd980a3935-full.png.html

Я делал такие приложения раньше, но здесь я столкнулся с проблемой - названия оружия, цены и расположение, кажется, скрыты подтег tbody, который пуст при поиске данных с помощью bs4.

Моя программа пока:

import requests
import bs4

url = requests.get('https://semlar.com/rivenprices/artax').text
soup = bs4.BeautifulSoup(url, 'html.parser')
data = soup.find(class_='table')

В этом случае data это:

<table class="table" id="riven-table">
<thead>
<tr>
<th>Riven Name</th>
<th class="price-avg">Avg Price</th>
<th class="riven-disposition">Dispo</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

Как видите, тег <tbody> пуст, но когда вы просматриваете какой-либо элемент из таблицы в вашем браузере, кажется, что он находится как раз внутри этого тега, под <tbody><tr><td> - вот скриншотс указанием части проверенного кода:

https://imggmi.com/full/2018/5/28/0619e4d1944c0291bfa70a30678b3f51-full.png.html

1 Ответ

0 голосов
/ 28 мая 2018

Вы знаете, что они говорят: Если они выбрасывают вас за дверь, возвращайтесь через окно.

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

  1. Открывает веб-браузер, ожидает фиксированное время до загрузки веб-страницы, автоматически нажимает Ctrl + A , снова ждет, нажимает Ctrl + C и закрывает браузер (или карту браузера, если их много).Здесь я использовал модули webbrowser, time и pywinauto.
  2. Вставляет буфер обмена в файл rawdata.txt.Я сделал это только для того, чтобы убедиться, что я не испортил свое тестирование, пока я пишу и запускаю код снова и снова путем случайного копирования некоторого текста.Я использовал pyperclip, чтобы сделать это.Позже файл открывается, и содержимое форматируется для создания словаря в форме {'weapon_name': ['mod_price', 'disposition'], 'next_weapon_name: [...], ...}.
  3. Наконец программа запрашивает у пользователя имя оружия, которое он хочет проверить, и предоставляет ему данные из словаря.Затем он может снова запустить цикл, чтобы спросить о другом пистолете или просто завершить программу.

Код:

from time import sleep
import webbrowser
import pywinauto.keyboard as pkbd
import pyperclip

url = 'https://semlar.com/rivenprices/lanka'


def greet():
    print("This app will get data from {}".format(url))
    print("You will be able to check riven mod price and disposition for desired weapon.")


def open_browser_get_to_clipboard():
    webbrowser.open(url)
    sleep(10)
    pkbd.SendKeys('^a')
    sleep(2)
    pkbd.SendKeys('^c')
    sleep(1)
    pkbd.SendKeys('%{F4}')


def write_to_file(fname):
    with open(fname, 'w+') as fin:
        fin.write(pyperclip.paste())


def format_data_from_file(fname):
    riven_database = dict()
    with open(fname, 'r') as fout:
        data = fout.read().split('\n')
        start_ind = data.index('Riven Name\tAvg Price\tDispo')
        formatted_data = data[start_ind + 1:]
        formatted_data = list(filter(None, formatted_data))

        for item in formatted_data:
            temp = item.split('\t')
            riven_database.update({temp[0]: [temp[1], temp[2]]})

        return riven_database


def ask_user_and_check(riven_dict):
    print("Which weapon would you like to look up for?")
    while True:
        decision = input(">>> ")
        if decision.upper() not in riven_dict.keys():
            print("Weapon name not found. Try again.")
            decision = input(">>> ")
        else:
            print("You have picked {} weapon to check.".format(decision.upper()))
            break

    return decision.upper()


def print_output(decision, riven_dict):
    print("Name of the weapon: {}".format(decision))
    print("Average riven mod price: {} platinum".format(riven_dict[decision][0]))
    print("Riven disposition of picked weapon: {}".format(riven_dict[decision][1]))


def quit_or_loop_again():
    print("Do you want to search again or quit?")
    print("To search again input any character, to quit input [x] or [X].")
    decision = input(">>> ")
    if decision in ['x', 'X']:
        print('Good bye.')
    else:
        main()


def main():
    greet()
    open_browser_get_to_clipboard()
    write_to_file('rawdata.txt')
    riven_database = format_data_from_file('rawdata.txt')
    decision = ask_user_and_check(riven_database)
    print_output(decision, riven_database)
    quit_or_loop_again()


if __name__ == '__main__':
    main()

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...