Webscrapping цены опционов NSE, используя Python BeautifulSoup, относительно исправления кодировки - PullRequest
0 голосов
/ 02 января 2019

Я немного новичок в просмотре веб-страниц и не привык к "tr" и "td" вещам и таким образом к этому сомнению Я пытаюсь повторить этот код Python 2.7 в моем Python 3 из этой темы 'https://www.quantinsti.com/blog/option-chain-extraction-for-nse-stocks-using-python'.

Этот старый код использует .ix для индексации, которую я легко могу исправить с помощью .iloc. Тем не менее, в строке отображается сообщение об ошибке «требуется байтоподобный объект, а не« str »», даже если я напишу его раньше.

Я проверил эту другую ссылку из stackoverflow и не смог решить мою проблему

Мне кажется, я заметил, почему это происходит. Это из-за предыдущего цикла for, использованного ранее для определения переменной tr. Если я пропущу эту строку, то получу DataFrame с числами с некоторым прикрепленным текстом. Я могу отфильтровать это с помощью цикла по всему DataFrame, но лучше использовать правильную функцию replace (). Я не могу понять это немного.

Вот мой полный код. Я пометил критические разделы кода, на который я ссылался, используя ######################### исключительно в строке, чтобы можно было найти строку быстро (даже по Ctrl + F):

import requests
import pandas as pd
from bs4 import BeautifulSoup

Base_url = ("https://nseindia.com/live_market/dynaContent/"+
        "live_watch/option_chain/optionKeys.jsp?symbolCode=2772&symbol=UBL&"+
        "symbol=UBL&instrument=OPTSTK&date=-&segmentLink=17&segmentLink=17")

page = requests.get(Base_url)
#page.status_code
#page.content

soup = BeautifulSoup(page.content, 'html.parser')
#print(soup.prettify())

table_it = soup.find_all(class_="opttbldata")
table_cls_1 = soup.find_all(id = "octable")

col_list = []

# Pulling heading out of the Option Chain Table

#########################
for mytable in table_cls_1:
    table_head = mytable.find('thead')

    try:
        rows = table_head.find_all('tr')
        for tr in rows:
            cols = tr.find_all('th')
            for th in cols:
                er = th.text
                #########################
                ee = er.encode('utf8')
                col_list.append(ee)
    except:
        print('no thread')

col_list_fnl = [e for e in col_list if e not in ('CALLS', 'PUTS', 'Chart', '\xc2\xa0')]
#print(col_list_fnl)

table_cls_2 = soup.find(id = "octable")
all_trs = table_cls_2.find_all('tr')
req_row = table_cls_2.find_all('tr')

new_table = pd.DataFrame(index=range(0,len(req_row)-3),columns = col_list_fnl)

row_marker = 0

for row_number, tr_nos in enumerate(req_row):
    if row_number <= 1 or row_number == len(req_row)-1:
        continue # To insure we only choose non empty rows

    td_columns = tr_nos.find_all('td')

    # Removing the graph column
    select_cols = td_columns[1:22]
    cols_horizontal = range(0,len(select_cols))

    for nu, column in enumerate(select_cols):

        utf_string = column.get_text()
        utf_string = utf_string.strip('\n\r\t": ')
        #########################
        tr = tr.replace(',' , '') # Commenting this out makes code partially work, getting numbers + text attached to the numbers in the table

        # That is obtained by commenting out the above line with tr variable & running the entire code.
        tr = utf_string.encode('utf8')

        new_table.iloc[row_marker,[nu]] = tr

    row_marker += 1

print(new_table)

Ответы [ 2 ]

0 голосов
/ 04 января 2019

При замене приведенных ниже строк кодов

tr = tr.replace(',' , '')
tr = utf_string.encode('utf8')
new_table.iloc[row_marker,[nu]] = tr

со следующим кодом, тогда он должен работать.

new_table.iloc[row_marker,[nu]] = utf_string.replace(',' , '')

Поскольку функция замены не работает с Unicode. Вы также можете рассмотреть возможность использования кода ниже для декодирования имен столбцов

col_list_fnl = [e.decode('utf8') for e in col_list if e not in ('CALLS', 'PUTS', 'Chart', '\xc2\xa0')]
col_list_fnl

Надеюсь, это поможет.

0 голосов
/ 02 января 2019

Для первого раздела:

er = th.text должно быть er = th.get_text()

Ссылка на документацию get_text

Для последнего раздела:

Глядя на это, ваша переменная "tr" на данный момент является последним тегом tr, найденным в супе с использованием for tr in rows.Это означает, что tr, который вы пытаетесь вызвать replace, - это навигационная строка, а не строка.

tr = tr.get_text().replace(',' , '') должен работать для первой итерации, однако, так как вы перезаписали его в первой итерации, он сломаетсяследующая итерация.

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

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