Найти .Не удивительно с Beautifulsoup4 - PullRequest
0 голосов
/ 03 мая 2018

Я пытаюсь получить (некоторое) содержимое таблицы из URL. До сих пор мне удалось получить два требуемых содержимого страницы, но есть третий (третий столбец), который я хотел бы получить только его текст. Проблема в том, что основная ссылка существует в другом месте на странице (с другим текстом), и если я хочу загрузить таблицу в базу данных SQL, содержимое третьего столбца не будет соответствовать первым двум столбцам.

import urllib2
from bs4 import BeautifulSoup4
startURL = "http://some.url/website.html"
page = urllib2.urlopen(startURL).read()
soup = BeautifulSoup(page, "html.parser")
for links in soup.findAll("a"):
    if "href" in links.attrs:
        www = links.attrs.values()
        if not "https://" in www[0]:  # to exclude all non-relative links, e.g. external links
            if "view/" in www[0]: # To get only my desired links of column 1
                link_of_column1 = www[0]   # this is now my wanted link

Хорошо, с помощью этого кода я могу получить второй столбец. Где и как мне применить функцию .nextsibling (), чтобы получить следующую ссылку в следующем (3-м) столбце?

Edit: Как меня спросили: URL-адрес https://myip.ms/browse/web_hosting/World_Web_Hosting_Global_Statistics.html, и я хочу получить содержимое из столбцов 2 и 3, а именно «Хостинговая компания» (ссылка-текст и ссылка) и «Страна» (только текст) .

Edit2: Еще одна вещь, которую я забыл ... как я могу извлечь информацию, что его 137,157 records?

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

Код: (Python 3.6+, используется f-strings)

import urllib.parse
from collections import namedtuple
from datetime import datetime

import bs4
import requests

HostingCompany = namedtuple('HostingCompany',
                            ('name', 'country', 'websites', 'usage', 'usage_by_top', 'update_time'))


class MyIpLink:
    url_base = 'https://myip.ms'

    def __init__(self, tag: bs4.element.Tag, *, is_anchor=False):
        a_tag = tag.find('a')

        if is_anchor:  # treat `tag` as an anchor tag
            a_tag = tag

        self.text = tag.text.strip()
        self.url = urllib.parse.urljoin(self.url_base, a_tag['href'])

    def __repr__(self):
        return f'{self.__class__.__name__}(text={repr(self.text)}, url={repr(self.url)})'


url = 'https://myip.ms/browse/web_hosting/World_Web_Hosting_Global_Statistics.html'
html = requests.get(url).text
soup = bs4.BeautifulSoup(html, 'html.parser')

rows = soup.select('#web_hosting_tbl > tbody > tr')[::2]  # skips "more info" rows
companies = []

for row in rows:
    tds = row.find_all('td')

    name = MyIpLink(tds[1])
    country = MyIpLink(tds[2])
    websites = [MyIpLink(a, is_anchor=True) for a in tds[3].find_all('a')]
    usage = MyIpLink(tds[4])
    usage_by_top = MyIpLink(tds[5])
    update_time = datetime.strptime(tds[6].text.strip(), '%d %b %Y, %H:%M')

    company = HostingCompany(name, country, websites, usage, usage_by_top, update_time)
    companies.append(company)

import pprint
pprint.pprint(companies)

print(companies[0].name.text)
print(companies[0].name.url)
print(companies[0].country.text)

Выход:

[HostingCompany(name=MyIpLink(text='Godaddy.com, LLC', url='https://myip.ms/view/web_hosting/2433/Godaddy_com_LLC.html'), country=MyIpLink(text='USA', url='https://myip.ms/view/best_hosting/USA/Best_Hosting_in_USA.html'), websites=[MyIpLink(text='www.godaddy.com', url='https://myip.ms/go.php?1229687315_ITg7Im93dCkWE0kNAhQSEh0FUeHq5Q==')], usage=MyIpLink(text='512,701 sites', url='https://myip.ms/browse/sites/1/ownerID/2433/ownerIDii/2433'), usage_by_top=MyIpLink(text='951 sites', url='https://myip.ms/browse/sites/1/rankii/100000/ownerID/2433/ownerIDii/2433'), update_time=datetime.datetime(2018, 5, 2, 5, 17)),
 HostingCompany(name=MyIpLink(text='Cloudflare, Inc', url='https://myip.ms/view/web_hosting/4638/Cloudflare_Inc.html'), country=MyIpLink(text='USA', url='https://myip.ms/view/best_hosting/USA/Best_Hosting_in_USA.html'), websites=[MyIpLink(text='www.cloudflare.com', url='https://myip.ms/go.php?840626136_OiEsK2ROSxAdGl4QGhYJG+Tp6fnrv/f49w==')], usage=MyIpLink(text='488,119 sites', url='https://myip.ms/browse/sites/1/ownerID/4638/ownerIDii/4638'), usage_by_top=MyIpLink(text='16,160 sites', url='https://myip.ms/browse/sites/1/rankii/100000/ownerID/4638/ownerIDii/4638'), update_time=datetime.datetime(2018, 5, 2, 5, 10)),
 HostingCompany(name=MyIpLink(text='Amazon.com, Inc', url='https://myip.ms/view/web_hosting/615/Amazon_com_Inc.html'), country=MyIpLink(text='USA', url='https://myip.ms/view/best_hosting/USA/Best_Hosting_in_USA.html'), websites=[MyIpLink(text='www.amazonaws.com', url='https://myip.ms/go.php?990446041_JyYhKGFxThMQHUMRHhcDExHj8vul7f75')], usage=MyIpLink(text='453,230 sites', url='https://myip.ms/browse/sites/1/ownerID/615/ownerIDii/615'), usage_by_top=MyIpLink(text='9,557 sites', url='https://myip.ms/browse/sites/1/rankii/100000/ownerID/615/ownerIDii/615'), update_time=datetime.datetime(2018, 5, 2, 5, 4)),
 ...
]

Godaddy.com, LLC
https://myip.ms/view/web_hosting/2433/Godaddy_com_LLC.html
USA

Собираюсь обновить ответ вечером с некоторыми пояснениями. Ура!

0 голосов
/ 03 мая 2018

Попробуйте следующий подход. Он должен дать вам тексты из column 2, ссылки из column 2 и снова тексты из column 3 из этой таблицы. Я использовал lxml вместо BeautifulSoup, чтобы сделать это быстрее. Спасибо.

import requests
from urllib.parse import urljoin
from lxml.html import fromstring

URL = 'https://myip.ms/browse/web_hosting/World_Web_Hosting_Global_Statistics.html'

res = requests.get(URL)
root = fromstring(res.text)

for items in root.cssselect('#web_hosting_tbl tr:not(.expand-child)')[1:]:
    name = items.cssselect("td.row_name a")[0].text
    link = urljoin(URL,items.cssselect("td.row_name a")[0].attrib['href'])
    country = items.cssselect("td a[href^='/view/best_hosting/']")[0].text
    print(name, link, country)

Результаты:

Godaddy.com, LLC https://myip.ms/view/web_hosting/2433/Godaddy_com_LLC.html USA
Cloudflare, Inc https://myip.ms/view/web_hosting/4638/Cloudflare_Inc.html USA
Amazon.com, Inc https://myip.ms/view/web_hosting/615/Amazon_com_Inc.html USA
Ovh Sas https://myip.ms/view/web_hosting/7593/Ovh_Sas.html France
Hetzner Online Ag https://myip.ms/view/web_hosting/45081/Hetzner_Online_Ag.html Germany
Hostgator.com Llc https://myip.ms/view/web_hosting/26757/Hostgator_com_Llc.html USA
Google Inc https://myip.ms/view/web_hosting/617/Google_Inc.html USA
0 голосов
/ 03 мая 2018

Сначала найдите таблицу, в которой есть вся информация, используя атрибут id=web_hosting_tbl. Затем переберите все строки таблицы. Но если вы посмотрите на источник страницы, нужные вам строки не являются последовательными, а чередуются, и у них нет имен классов. Кроме того, первая строка таблицы является строкой заголовка, поэтому мы должны пропустить это.

После получения необходимых строк (используя table.find_all('tr')[1::2]) найдите все столбцы, а затем получите необходимую информацию из соответствующих столбцов.

Код:

import requests
from bs4 import BeautifulSoup

r = requests.get('https://myip.ms/browse/web_hosting/World_Web_Hosting_Global_Statistics.html')
soup = BeautifulSoup(r.text, 'lxml')

table = soup.find('table', id='web_hosting_tbl')
for row in table.find_all('tr')[1::2]:
    all_columns = row.find_all('td')
    name = all_columns[1].a.text
    link = all_columns[1].a['href']
    country = all_columns[2].a.text
    print(name, link, country, sep=' | ')

Частичный вывод:

Godaddy.com, LLC | /view/web_hosting/2433/Godaddy_com_LLC.html | USA
Cloudflare, Inc | /view/web_hosting/4638/Cloudflare_Inc.html | USA
Amazon.com, Inc | /view/web_hosting/615/Amazon_com_Inc.html | USA
Ovh Sas | /view/web_hosting/7593/Ovh_Sas.html | France
Hetzner Online Ag | /view/web_hosting/45081/Hetzner_Online_Ag.html | Germany
Hostgator.com Llc | /view/web_hosting/26757/Hostgator_com_Llc.html | USA
Google Inc | /view/web_hosting/617/Google_Inc.html | USA
Bluehost Inc | /view/web_hosting/3886/Bluehost_Inc.html | USA
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...