Как вы перебираете HTML-ссылки в таблице для извлечения данных из таблиц? - PullRequest
0 голосов
/ 13 января 2019

Я пытаюсь прокрутить таблицу на https://bgp.he.net/report/world. Я хотел бы просмотреть каждую из HTML-ссылок, переходящих на страницы стран, затем получить данные и затем перейти к следующему списку. Я использую красивый суп и уже могу получить нужные данные, но не могу понять, как перебрать столбец HTML.

from bs4 import BeautifulSoup
import requests
import json


headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0'}

url = "https://bgp.he.net/country/LC"
html = requests.get(url, headers=headers)

country_ID = (url[-2:])
print("\n")

soup = BeautifulSoup(html.text, 'html.parser')
#print(soup)
data = []
for row in soup.find_all("tr")[1:]: # start from second row
    cells = row.find_all('td')
    data.append({
        'ASN': cells[0].text,
        'Country': country_ID,
        "Name": cells[1].text,
        "Routes V4": cells[3].text,
        "Routes V6": cells[5].text
    })



i = 0

with open ('table_attempt.txt', 'w') as r:
    for item in data:
        r.write(str(data[i]))
        i += 1
        r.write("\n")


print(data)

Я хотел бы иметь возможность собрать данные из каждой страны в один письменный текстовый файл.

Ответы [ 3 ]

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

Вы можете перебрать основную таблицу и отправить запрос на очистку списка "report":

import requests, re
from bs4 import BeautifulSoup as soup
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0'}
def scrape_report(_id):
  _d = soup(requests.get(f'https://bgp.he.net/country/{_id}', headers=headers).text, 'html.parser')
  _headers = [i.text for i in _d.find_all('th')]
  _, *data = [[i.text for i in b.find_all('td')] for b in _d.find_all('tr')]
  return [dict(zip(_headers, i)) for i in data]

d = soup(requests.get('https://bgp.he.net/report/world', headers=headers).text, 'html.parser')
_, *_listings = [[re.sub('[\t\n]+', '', i.text) for i in b.find_all('td')] for b in d.find_all('tr')]
final_result = [{**dict(zip(['Name', 'Country', 'ASN'], [a, b, c])), 'data':scrape_report(b)} for a, b, c, *_ in _listings]
0 голосов
/ 15 января 2019
import requests
import json


headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0'}
url = "https://bgp.he.net/report/world"
html = requests.get(url, headers=headers)

soup = BeautifulSoup(html.text, 'html.parser')

#sorting through table
table = soup.find('table', {'id':'table_countries'})
rows = table.find_all('tr')

country_urls = []

#Grabbing urls from table
for row in rows:
    try:
        link = row.select('a')[0]['href']
        country_urls.append(link)
    except:
        continue


Total_URLs= len(country_urls)


print(Total_URLs, "counties to pull data from")
print("\n")

#Creating text file
with open('table_attempt.txt', 'w', encoding="utf-8") as r:
    json.dumps([])


#Looping through country url list
    for link in country_urls:

        url = "https://bgp.he.net" + link
        html = requests.get(url, headers=headers)

#Taking country identifier from url list
        country_ID = (url[-2:])

        soup = BeautifulSoup(html.text, 'html.parser')

        data = []

        i=0
        Total_URLs -= 1

#appending to file
        with open('ASN_Info.txt', 'a', encoding="utf-8") as r:
            for row in soup.find_all("tr")[1:]: # start from second row
                cells = row.find_all('td')
                data.append({
                    'ASN': cells[0].text,
                    'Country': country_ID,
                    "Name": cells[1].text,
                    "Routes V4": cells[3].text,
                    "Routes V6": cells[5].text
                })
                json.dump(data[i], r)
                i += 1
                r.write("\n")

            print('Currently writing from data from %s. %s countries left to pull data from.' %(country_ID, Total_URLs))
0 голосов
/ 13 января 2019

Я проверял это только с первыми 3 ссылками (получил одну ошибку с UnicodeEncodeError, но исправил это и прокомментировал, где это было в коде).

from bs4 import BeautifulSoup
import requests
import json

#First get the list of countries urls

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0'}

url = "https://bgp.he.net/report/world"
html = requests.get(url, headers=headers)

soup = BeautifulSoup(html.text, 'html.parser')

table = soup.find('table', {'id':'table_countries'})
rows = table.find_all('tr')

country_urls = []

# Go through each row and grab the link. If there's no link, continue to next row
for row in rows:
    try:
        link = row.select('a')[0]['href']
        country_urls.append(link)
    except:
        continue


# Now iterate through that list
for link in country_urls:

    url = "https://bgp.he.net" + link
    html = requests.get(url, headers=headers)

    country_ID = (url[-2:])
    print("\n")

    soup = BeautifulSoup(html.text, 'html.parser')
    #print(soup)
    data = []
    for row in soup.find_all("tr")[1:]: # start from second row
        cells = row.find_all('td')
        data.append({
            'ASN': cells[0].text,
            'Country': country_ID,
            "Name": cells[1].text,
            "Routes V4": cells[3].text,
            "Routes V6": cells[5].text
        })



    i = 0
    print ('Writing from %s' %(url))

    # I added encoding="utf-8" because of an UnicodeEncodeError:
    with open ('table_attempt.txt', 'w', encoding="utf-8") as r:
        for item in data:
            r.write(str(data[i]))
            i += 1
            r.write("\n")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...