使用Python BeautifulSoup Webscrapping NSE期权价格,有关编码校正

时间:2019-01-02 12:21:47

标签: python beautifulsoup character-encoding

我对网页抓取有点陌生,不习惯“ tr”和“ td”之类的东西,因此对此产生了疑问。我正在尝试从此线程“ https://www.quantinsti.com/blog/option-chain-extraction-for-nse-stocks-using-python”在Python 3中复制此Python 2.7代码。

此旧代码使用.ix进行索引,我可以轻松使用.iloc进行更正。但是,该行显示错误“即使我之前写过,也需要一个类似字节的对象,而不是“ str”。

我已经从stackoverflow中检查了另外link,但无法解决我的问题

我想我已经发现了为什么会这样。这是因为先前用于定义变量tr的for循环。如果我省略了这一行,那么我将获得一个带有数字的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 :(得分:0)

对于第一部分:

er = th.text应该是er = th.get_text()

Link to get_text documentation

对于后一部分:

看一下,此时的“ tr”变量是使用for tr in rows在汤中找到的最后一个tr标记。这意味着您尝试调用replace的tr是可导航的字符串,而不是字符串。

tr = tr.get_text().replace(',' , '')应该适用于第一次迭代,但是由于您在第一次迭代中已将其覆盖,因此它将在下一次迭代中中断。

另外,感谢您提出问题的深度。虽然您并没有提出这个问题,但是非常感谢您花费大量时间描述自己遇到的麻烦以及尝试过的代码。

答案 1 :(得分:0)

如果替换下面的代码行

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

使用以下代码,它应该可以工作。

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

因为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

我希望这会有所帮助。