Web抓取:索引超出范围(可能发生缩放错误)

时间:2019-01-14 23:10:10

标签: python python-3.x

嗨,编写了一个Web剪贴程序,它正确获取了ASN编号,但是在所有数据被剪贴之后,它会返回错误“ Array Out if Bounds”。

我正在使用Pycharm和最新的python版本。下面是我的代码。 在stackoverflow上已经存在类似的问题,但是我无法将各个部分放在一起并使其正常工作。 (Web Scrapping List Index Out Of Range)完全相同的错误,但是我不确定如何使其适用于我的列表。

错误似乎出在current_country = link.split('/')[2] 任何帮助表示赞赏。谢谢。

import urllib.request
import bs4
import re
import json


url = 'https://ipinfo.io/countries'
SITE = 'https://ipinfo.io'

def url_to_soup(url):
    req = urllib.request.Request(url)
    opener = urllib.request.build_opener()
    html = opener.open(req)
    soup = bs4.BeautifulSoup(html, "html.parser")
    return soup


def find_pages(page):
    pages = []
    for link in page.find_all(href=re.compile('/countries')):
        pages.append(link.get('href'))
    return pages


def scrape_pages(links):
    mappings = {}

    print("Scraping Pages for ASN Data...")

    for link in links:
        country_page = url_to_soup(SITE + link)
        current_country = link.split('/')[2]
        print(current_country)
        for row in country_page.find_all('tr'):
            columns = row.find_all('td')
            if len(columns) > 0:
                current_asn = re.findall(r'\d+', columns[0].string)[0]
                print(current_asn)
                """
                name = columns[1].string
                routes_v4 = columns[3].string
                routes_v6 = columns[5].string
                mappings[current_asn] = {'Country': current_country,
                                     'Name': name,
                                     'Routes v4': routes_v4,
                                     'Routes v6': routes_v6}
      return mappings """


main_page = url_to_soup(url)

country_links = find_pages(main_page)
#print(country_links)

asn_mappings = scrape_pages(country_links)
print(asn_mappings)

1 个答案:

答案 0 :(得分:2)

https://ipinfo.io/countries中最后一个href包含字符串“ /countries”实际上是“ /countries”:

<li><a href="/countries">Global ASNs</a></li>

分割此链接后,它产生了列表["", "countries"],其中缺少第三个元素。要解决此问题,只需在获取第三个元素之前检查列表长度即可:

        ...
        current_country = link.split('/')
        if len(current_country) < 3:
            continue
        current_country = current_country[2]
        ...

另一种解决方案是通过将正则表达式更改为:排除最后一个href

    ...
    for link in page.find_all(href=re.compile('/countries/')):
        ...