python-3.x TypeError:切片索引必须为整数或None,或者在抓取帮助页时出现__index__方法错误

xqkwcwgp  于 2023-01-03  发布在  Python
关注(0)|答案(1)|浏览(134)

我创建了python脚本来抓取facebook*帮助页面 *。我想抓取cms_object_idcmsIDname。所以这些值在一个脚本标签中,然后首先尝试找到所有<script>标签,然后尝试迭代这个标签,然后在标签中有__bbox,其中包含想要抓取的值。
这是我剧本:

import json
import requests
import bs4
from Essentials import Static

class CmsIDs:
    def GetIDs():
        # cont = requests.get(""https://www.facebook.com:443/help"", headers=Static.headers) # syntax error
        cont = requests.get("https://www.facebook.com:443/help", headers=Static.headers)
        soup = bs4.BeautifulSoup(cont.content, "html5lib")

        text = soup.find_all("script")

        start = ""
        txtstr = ""

  

        for i in range(len(text)):
    
            mystr = text[i]

            # mystr = text[i]
            print("this is: ", mystr.find('__bbox":'))
            if text[i].get_text().find('__bbox":') != -1:
                # print(i, text[i].get_text())
                txtstr += text[i].get_text()
                start = text[i].get_text().find('__bbox":') + len('__bbox":')

        print('start:', start)

        count = 0
        for end, char in enumerate(txtstr[start:], start):
            if char == '{':
                count += 1
            if char == '}':
                count -= 1
            if count == 0:
                break
        print('end:', end)

        # --- convert JSON string to Python structure (dict/list) ---

        data = json.loads(txtstr[start:end+1])
        # pp.pprint(data)
        print('--- search ---')
        CmsIDs.search(data)

        # --- use recursion to find all 'cms_object_id', 'cmsID', 'name' ---

    def search(data):
        if isinstance(data, dict):
            found = False
            if 'cms_object_id' in data:
                print('cms_object_id', data['cms_object_id'])
                found = True
            if 'cmsID' in data:
                print('cmsID', data['cmsID'])
                found = True
            if 'name' in data:
                print('name', data['name'])
                found = True
            if found:
                print('---')
            for val in data.values():
                CmsIDs.search(val)
        if isinstance(data, list):
            for val in data:
                CmsIDs.search(val)

if __name__ == '__main__':
    CmsIDs.GetIDs()

该页包含cms_object_idcmsIDname。所以想刮所有这3个值,但我得到一个错误:

for end, char in enumerate(txtstr[start:], start):
TypeError: slice indices must be integers or None or have an __index__ method

那么我怎样才能解决这个错误并达到最终目标呢?

busg9geu

busg9geu1#

    • 注意:**由于我不熟悉Essentials并且安装失败,同时由于 * ""https://www.facebook.com:443/help""*引发了语法错误(字符串的每一侧只能有一个引号),我更改了代码中的requests行。
cont = requests.get('https://www.facebook.com:443/help', headers={'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'})
TypeError: slice indices must be integers or None or have an __index__ method

start初始化为字符串[* start = "" *],它必须是整数。除非输入 * if text[i].get_text().find('__bbox":') != -1.... * 块,否则start仍为字符串。
如果你只是不想得到这个错误,你可以只是退出程序,如果start还没有更新[表明__bbox":是不是在任何script标签中找到].

print('start:', start)
        if start == "":
            print('{__bbox":} not found')
            return

        count = 0

但这仍然留下了__bbox":没有被发现的问题;我不知道 * 为什么 ,但如果我不使用html5lib解析器,这个问题就解决了--只需改为*BeautifulSoup(cont.content)**就解决了 * 这个 * 问题。

# soup = bs4.BeautifulSoup(cont.content, "html5lib")
        soup = bs4.BeautifulSoup(cont.content) # don't define the parser 
        # soup = bs4.BeautifulSoup(cont.content, "html.parser") # you could also try other parsers
其他建议

如果没有这些,您的代码可能也能正常工作,但您可能需要考虑以下建议的错误处理改进:

筛选script标记

如果text ResultSet只有包含__bbox":script标记,则可以避免不必要地遍历100多个其他script,并且不必再检查if....find('__bbox":')

text = soup.find_all(lambda t: t.name == 'script' and '"__bbox"' in t.get_text())

        for mystr in [s.get_text() for s in text]:
            print("this is: ", mystr.find('__bbox":'))
            txtstr += mystr
            start = mystr.find('__bbox":') + len('__bbox":')

启动end

您应该在 * for end, char ... * 循环之前初始化end变量[类似于end = 0],因为您也在循环之后使用它。

print('end:', end)
data = json.loads(txtstr[start:end+1])

如果txtstr[start:]为空,这些行将引发error/s,因为end尚未定义。

使用JavaScript解析器

这将使前面的建议变得不必要,但是如果txtstr[start:end+1]为空,或者如果它包含任何不成对的[可能转义的] }{json.loads将引发错误。因此,使用解析器可能比尝试遍历字符串更可靠。
我有一个this function,它使用slimit从包含JavaScript代码的字符串中查找值。(它远非完美,但至少对这个脚本来说似乎是完美的。)GetIDs()可以重写如下。

# import json, requests, bs4, slimit
# from slimit.visitors import nodevisitor 
# def findObj_inJS... ## PASTE FROM https://pastebin.com/UVcLniSG

# class CmsIDs:
    def GetIDs():
        # cont=requests.get('https://www.facebook.com:443/help',headers=Static.headers)
        cont = requests.get('https://www.facebook.com:443/help', headers={
            'accept': ';'.join(
                [ 'text/html,application/xhtml+xml,application/xml',
                  'q=0.9,image/avif,image/webp,image/apng,*/*',
                  'q=0.8,application/signed-exchange',
                  'v=b3', 'q=0.9'  ])})

        ## in case of request errors ##
        try: cont.raise_for_status()
        except Exception as e:
            print('failed to fetch page HTML -', type(e), e)
            return
        print('fetched', cont.url, 'with', cont.status_code, cont.reason)

        soup = bs4.BeautifulSoup(cont.content)
        scrCond = lambda t: t.name == 'script' and '"__bbox"' in t.get_text()
        jScripts = [s.get_text() for s in soup.find_all(scrCond)] 
        print(f'Found {len(jScripts)} script tags containing {{"__bbox"}}')

        data = [findObj_inJS(s,'"__bbox"') for s in jScripts]
        print('--- search ---')
        CmsIDs.search(data) 

    # def search(data)....

返回数据

这不是为了处理错误,但是如果您返回由CmsIDs.search打印的数据,您可以保存它以备将来使用。

def search(data):
        rList, dKeys = [], ['cms_object_id', 'cmsID', 'name']
        if isinstance(data, dict):
            dObj = {k: data[k] for k in dKeys if k in data}
            rList += [dObj] if dObj else []

            for k, v in dObj.items(): print(k, v)
            if dObj: print('---')

            for val in data.values(): rList += CmsIDs.search(val)
        if isinstance(data, list):
            for val in data: rList += CmsIDs.search(val)
        return rList

printed result将与以前相同,但如果您**将GetIDs**的最后一行更改为

return CmsIDs.search(data)

然后定义一个变量 * cmsList = CmsIDs.GetIDs() *,则cmsList将成为list of dctionaries,然后[例如]可以使用pandas将其保存为csv,并在电子表格上以表格形式查看。

# import pandas
pandas.DataFrame(cmsList).to_csv('CmsIDs_GetIDs.csv', index=False)

print the markdown,以获取下面的[我得到的结果]表

print(pandas.DataFrame(cmsList, dtype=str).fillna('').to_markdown())

| [索引]| cms对象标识|姓名|配置管理系统ID|
| - ------| - ------| - ------| - ------|
| 无||了解我的想法Facebook||
| 1个|小行星5707|科托夫霍珀雷东纳奥格利亚科夫霍格霍茨拉||
| 第二章|小行星39652|您的个人资料||
| 三个||沃奥达拉·特米恩拉·德奥达拉·格库夫拉·特米恩·沃奥达拉·特米恩拉|小行星1017|
| 四个||瓦萨西奥西诺夫内奥西诺夫内奥萨西诺夫内奥萨西诺夫内奥萨西诺夫内奥萨西诺夫|小行星1217373834962306|
| 五个||大波兰人波兰人波兰人波兰人波兰人波兰人波兰人波兰人波兰人波兰人波兰人波兰人波兰人波兰|小行星164026|
| 六个||瓦塞奥内内内内内内内内|小行星19112|
| 七|小行星154034|沃霍达夫拉·纳尼亚索夫||
| 八个||沃霍达夫拉·纳尼亚·奥德尔格兹夫|小行星2467504|
| 九||学习|小行星3363|
| 十个||控制谁可以添加好友和关注您|小行星2739483996|
| 十一||将您的联系人上传到Facebook|小行星1041|
| 十二||这是一个很好的例子。|小行星1000|
| 十三|小行星312| Facebook交友||
| 十四|小行星7537|瓦萨卡格奥廖夫讷拉斯托托托奥廖内卡拉||
| 十五||Feed的工作原理|小行星11555|
| 十六||控制您在Feed中看到的内容|小行星9641546403|
| 十七||喜欢和回应帖子|小行星1624|
| 十八||波沃希欧克|821153694683665|
| 十九||翻译源|小行星11950|
| 二十个||回忆|小行星1056|
| 二十一|小行星107|波夫吉奥默·列因讷||
| 二十二||拉德塞西利亚讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷讷|小行星48715|
| 二十三||帕普雷耶格利亚内奥伊特蒂沃夫西奥伊特里亚内奥伊特里亚内奥伊内|小行星1117|
| 二十四||两个孩子|小行星968185709965912|
| 二十五||布达韦奥夫西克利西克|小行星28763|
| 二十六||解决问题|小行星1024559617598844|
| 二十七|小行星753046815|卷轴||
| 二十八||监视卷轴|小行星475378724739085|
| 二十九||创建卷轴|小行星8676903|
| 三十||管理卷盘|小行星590925|
| 三十一|小行星862|罗泽普夫戈代||
| 三十二||к с т в о р и т и р о з п о в|小行星126560|
| 三十三||查看和回复文章|小行星|
| 三十四||页面故事|小行星425367811379971|
| 三十五|小行星106952|塞夫查德利涅涅涅耶夫戈韦奥||
| 三十六||茨夫西加特利尼|小行星17037|
| 三十七||奥夫盖韦约|小行星1738|
| 三十八||上线|931327837299966|
| 三十九||专辑|小行星490693|
| 四十||沃霍达夫拉讷讷讷|小行星2676|
| 四十一||锡翁内内·珀罗伯莱米|小行星507253|
| 四十二|小行星1041553655923544|韦达韦奥乌达手表||
| 四十三||帕夫拉·格利亚·达沃伊奥|小行星4012|
| 四十四||解决问题|小行星2700|
| 四十五|小行星24026|游戏||
| 四十六||Facebook上的游戏|小行星385|
| 四十七||帕莱拉特耶夫·吉格拉尔·阿兴|小行星24847106|
| 四十八|小行星2824|科托托普里因克西||

| 四十九||与页面交互|小行星1771297453|
| 五十||科塔夫托布拉|小行星1352|
| 五十一||米纳纳拉·科波勒·塞西查托夫拉·阿切夫|小行星1644118259243888|
| 五十二||卡耶拉乌夫拉南南南南南南南南南南南南|小行星1206|
| 五十三||自定义页面|小行星16024|
| 五十四||出版|小行星15332|
| 五十五||信息传递|小行星9944|
| 五十六||见解|小行星794890|
| 五十七||班宁与节制|小行星248844|
| 五十八||沃塞古内古特蒂佩普罗奥布格利亚米古|小行星102013|
| 五十九|小行星16297|古尔皮耶||
| 六十||加入并选择您的设置|小行星1210|
| 六十一||发布、参与和隐私|小行星530628541|
| 六十二||创建、参与和管理设置|小行星408334464841405|
| 六十三||克耶普列夫拉内内内内内内内内内内内内内内内|小行星168667|
| 六十四||社区聊天|小行星33973|
| 六十五||组中的页面|小行星1769476376397|
| 六十六||解决问题|小行星107536|
| 六十七|小行星1076296042409786|波奥达吉伊||
| 六十八||创建和管理事件|小行星572885262883136|
| 六十九||查看和响应事件|小行星157|
| 七十||Facebook课程|小行星804063|
| 七十一|八三三一四四一五三七四五六四三|筹款及捐款||
| 七十二||创建募捐者|小行星3566804014|
| 七十三||帕夫特洛夫|小行星1409509059|
| 七十四||奥斯科布季斯查泽布季科科奇查季夫|小行星332|
| 七十五||非营利组织|小行星164000|
| 七十六||解决问题|小行星27255|
| 七十七|小行星143440| meta支付||
| 七十八||帕莱拉特耶夫·吉格拉尔·阿兴|小行星24847106|
| 七十九||消息中的付款|小行星86317120|
| 八十||帕夫特洛夫|小行星1409509059|
| 八十一||克里夫特克辛纳扎扎赫卡奥代米西|小行星1769557403280350|
| 八十二||货币化和支出|小行星17378|
| 八十三|小行星1713|市场||
| 八十四||к пра执行|小行星188906|
| 八十五||在市场上购买|小行星272975|
| 八十六||波兰大市场|小行星15383|
| 八十七||在Marketplace上随运费销售|小行星773379|
| 八十八||在Facebook上使用结算|小行星14112|
| 八十九||格吕普蒂泽卡吕普蒂夫|小行星31976|
| 九十||获取市场帮助|小行星1127970530677256|
| 九十一|小行星1642|沃奥戈拉特克米||
| 九十二||管理您的应用程序|小行星942196655898243|
| 九十三||瓦迪米提西查里什科翁·沃迪米翁·沃迪米翁·沃迪米翁·沃迪米翁·沃迪米翁|小行星172760|
| 九十四|小行星866249956813928|脸谱网广告||
| 九十五||机器人|小行星163991|
| 九十六||iPhone和iPad应用程序|小行星115802|
| 九十七||Facebook精简版应用程序|小行星795|
| 九十八|小行星273|塞普涅执行任务||
| 九十九||克耶拉乌夫拉东东尼奥戈德堡利科夫拉||
| 一百|小行星1573156092981|瓦赫西达瓦普拉罗德利什||
| 一百零一||沃切戈夫·奥格利·科夫米耶·泽拉·佩米耶|小行星10580336|
| 一百零二||我的|小行星248|
| 一百零三||沃斯派拉夫·列东内·沃斯派拉夫·列东内|小行星2831004|
| 一百零四||拉夫拉翁塔翁塔翁翁翁尼亚东索索索索夫|小行星582|
| 一百零五|小行星2390|拉利拉斯查托夫拉内内纳科奥格利什科夫戈戈泽拉佩米西托||
| 一百零六||к|小行星12212|
| 一百零七||拉斯切 iis 基亚科波勒西查乌夫拉切什|小行星174015|
| 一百零八||瑟帕德科季什特|小行星991335594313139|
| 一百零九|小行星1090|脸书||
| 一百一十|小行星1036755649750898|塞普诺夫·吉耶东||
| 一百一十一||推送、电子邮件和文本通知|小行星530|
| 一百一十二||瓦耶雷吉|小行星2698804|
| 一百一十三||瓦塞奥内内内内内内内内|小行星1719980|
| 一百一十四|小行星1093|拉利拉斯切托乌夫拉内内内阿索雷克利拉米蒂||
| 一百一十五||脸书|小行星516|
| 一百一十六||卡辛查托洛德利什查托洛德利什查托,也就是说查托洛德利什查托|小行星10758805|
| 一百一十七||打开它打开它Facebook|小行星6104|
| 一百一十八|小行星17017|世界杯足球赛||
| 一百一十九|小行星25056391|瓦赫拉克特夫拉执行公司||
| 一百二十||科宁·费尔扎格||
| 一百二十一|小行星238318|瓦萨萨卡科翁·瓦萨盖翁·赫翁·赫翁·赫翁||
| 一百二十二||快速输入,输入,输入,输入,输入Facebook|小行星12975022535|
| 一百二十三||克海尔乌夫拉·纳尼亚·塞弗霍伊蒂米耶·沃莫普米耶·塞萨米耶|小行星504765303045427|
| 一百二十四||控制可以找到您的人员|小行星1718|
| 一百二十五|小行星5926793|沃伊茨韦凯卡勒||
| 一百二十六||世界杯足球赛|小行星72670|
| 一百二十七||塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚人塞尔维亚|小行星1553737468262661|
| 一百二十八||危机应对|小行星1418745|
| 一百二十九||塞尔维亚塞尔维亚塞尔维亚塞尔维亚|小行星1079477|
| 一百三十||因尼沃尔默塔执行计划|小行星764592|
| 一百三十一|小行星235|拉喀西查托奥布格利科夫霍格奥茨拉佩米西古||
| 一百三十二||在执行任务时|小行星28569571|
| 一百三十三||东波夫·西波夫·西波夫|小行星9092431|
| 一百三十四||在我面前|小行星1584|
| 一百三十五|小行星23607|东东东东东东东东东东东东东东东||
| 一百三十六||俄罗斯|小行星1086|
| 一百三十七||乌克兰|小行星|
| 一百三十八||市场|小行星721562085854101|
| 一百三十九||波洛拉达迪米蒂奥蒂奥蒂奥蒂奥蒂奥蒂奥蒂奥蒂奥蒂奥蒂|小行星1238841|

| 一百四十||克戈普戈恩|小行星159924|
| 一百四十一||波夫利什卡塔西卡帕尔格米蒂||
| 一百四十二|小行星17537|塞卡帕尔格拉讷讷讷帕波帕尔格谢耶讷讷讷讷||
| 一百四十三||你是谁?|小行星13804|
| 一百四十四||还没有帐户?|小行星17234005|
| 一百四十五|小行星112662| Facebook的联系人Facebook的联系人||
| 一百四十六|小行星1866|在Facebook上做真实的自己||
| 一百四十七|小行星15614|波夫扎达沃门德夫扎达沃门德夫扎达沃||
| 一百四十八|小行星121634951|三里拉米纳查塔瓦里拉利什切耶夫||
| 一百四十九|小行星275013|克耶鲁夫拉·纳尼亚·奥格·列·科夫拉·德·斯·特·德·拉·列·列·列·列·达·内||
| 一百五十||关于记忆帐户|小行星101771|
| 一百五十一||请求记住或删除帐户|小行星1111|
| 一百五十二|小行星3992|因讷特莱伊科塔德利赫纳夫莱拉塞内塞内赫||
| 一百五十三||阿夫托托托赫尔什卡涅普拉夫|小行星10206|
| 一百五十四||托 perl 戈夫夫·费利什纳·默塔· perl 卡|小行星50766368942|
| 一百五十五|小行星17354430|帕夫罗纳拉斯切瓦波德利切蒂克米蒂||

相关问题