Python, 'IndexError: список индексов вне диапазона' при разборе больших массивов BeautifulSoup - PullRequest
0 голосов
/ 13 января 2020

Я продолжаю получать следующую ошибку:

Traceback (most recent call last):
  File "C:\Users\User\Documents\Project.py", line 100, in <module>
    parseData(array)
  File "C:\Users\User\Documents\Project.py", line 91, in parseData
    name2 = pageSoup.findAll('div', {'class': 'item-title'})[0].string
IndexError: list index out of range

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

def parseData(urls):
    f = io.open('output.txt', 'a', encoding='utf-8')
    for url in urls:
        response = urllib.request.urlopen(url)
        responseContent = response.read()
        pageSoup = BeautifulSoup(responseContent, 'html.parser', from_encoding="utf-8")
        if 'https://example.com' in url:
            name = pageSoup.findAll('h3', {'class': 'tb-main-title'})[0].string
            price = pageSoup.findAll('em', {'class': 'tb-rmb-num'})[0].string
            link = url
            print('Retriving data from ' + str(link) + '...\n' + str(name) + ':' + str(price))
            f.write('\n' + str(link) + '\n' + str(name) + '\n' + str(price) + '\n')

        elif 'https://example2.com' in url:
            name2 = pageSoup.findAll('div', {'class': 'item-title'})[0].string
            price2 = pageSoup.findAll('span', {'class': 'cur-price'})[0].string
            print('Retriving data from ' + str(link) + '...\n' + str(name2) + ':' + str(price2))
            f.write('\n' + str(link) + '\n' + str(name2) + '\n' + str(price2) + '\n')

Спасибо, что нашли время, чтобы проверить это, любая помощь очень ценится! :)

Ответы [ 2 ]

1 голос
/ 13 января 2020

Это улучшение выше ответа

import urllib.request
from bs4 import BeautifulSoup
from collections import namedtuple
Data = namedtuple('Data', 'link name price')

def parseData(url):
    link = None
    name = None
    price = None

    with urllib.request.urlopen(url) as response:
        if response:
            # responseContent = response.read()
            pageSoup = BeautifulSoup(response, 'html.parser', from_encoding="utf-8")
            if 'https://example.com' in url:
                try:
                    name = pageSoup.findAll('h3', {'class': 'tb-main-title'})[0].string
                    price = pageSoup.findAll('em', {'class': 'tb-rmb-num'})[0].string
                except IndexError as e:
                    pass
            elif 'https://example2.com' in url:
                breakpoint()
                try:
                    name = pageSoup.findAll('div', {'class': 'item-title'})[0].string
                    price = pageSoup.findAll('span', {'class': 'cur-price'})[0].string
                except IndexError as e:
                    pass
            link = url
            print('Retriving data from ' + str(link) + '...\n' + str(name) + ':' + str(price))
        return Data(link=link, name=name, price=price)


urls = ["https://www.yahoo.com", "https://www.google.com"]


if __name__ == "__main__":
    for url_ in urls:
        data = parseData(url_)
        if data.link and data.name and data.price:
            with open('output.txt', 'a', encoding='utf-8') as f:
                f.write('\n' + str(link) + '\n' + str(name) + '\n' + str(price) + '\n')

1 голос
/ 13 января 2020

Существует ошибка IndexError, и я думаю, что обе проблемы можно решить следующим образом:


import urllib.request

def parseData(url):
    with urllib.request.urlopen('url') as response:
        if response:
            responseContent = response.read()
            pageSoup = BeautifulSoup(responseContent, 'html.parser', from_encoding="utf-8") 
            if 'https://example.com' in url:
                try:
                    name1 = pageSoup.findAll('h3', {'class': 'tb-main-title'})[0].string
                    price1 = pageSoup.findAll('em', {'class': 'tb-rmb-num'})[0].string
                except IndexError as e:
                    pass
                else:
                    link = url
                    print('Retriving data from ' + str(link) + '...\n' + str(name1) + ':' + str(price1))
                    yield (link, name1, price1)
            elif 'https://example2.com' in url:
                try:
                    name2 = pageSoup.findAll('div', {'class': 'item-title'})[0].string
                    price2 = pageSoup.findAll('span', {'class': 'cur-price'})[0].string
                except IndexError as e:
                    pass
                else:
                    print('Retriving data from ' + str(link) + '...\n' + str(name2) + ':' + str(price2))
                    yield (link, name2, price2)






urls = ["list of urls here"]


if __name__ == "main":
    for url_ in urls:
        link, name, price = parseData(url_)
        with open('output.txt', 'a', encoding='utf-8') as f:
            f.write('\n' + str(link) + '\n' + str(name) + '\n' + str(price) + '\n')

Этот код добавляет контекст менеджера и некоторые проверки, которые могут избежать некоторых ошибок

...