Web-scraping: пустой набор данных после сбора информации - PullRequest
2 голосов
/ 08 апреля 2020

Я хотел бы создать набор данных, включающий информацию, скопированную с веб-сайта. Я объясняю, что я сделал, и ожидаемый результат ниже. Я получаю пустые массивы для строк и столбцов, а затем для всего набора данных, и я не понимаю причину. Надеюсь, вы мне поможете.

1) Создайте пустой фрейм данных только с одним столбцом: этот столбец должен содержать список URL для использования.

data_to_use = pd.DataFrame([], columns=['URL'])

2) Выберите URL-адреса из предыдущего набора данных.

select_urls=dataset.URL.tolist()

Этот набор URL-адресов выглядит следующим образом:

                             URL
0                     www.bbc.co.uk
1             www.stackoverflow.com           
2                       www.who.int
3                       www.cnn.com
4         www.cooptrasportiriolo.it
...                             ...

3) Заполните столбец этими urls:

data_to_use['URL']= select_urls
data_to_use['URLcleaned'] = data_to_use['URL'].str.replace('^(www\.)', '')

4) Выберите случайную выборку для проверки: первые 50 строк в столбце URL

data_to_use = data_to_use.loc[1:50, 'URL']

5) Попробуйте очистить информацию

import requests
import time
from bs4 import BeautifulSoup

urls= data_to_use['URLcleaned'].tolist()

ares = []

for u in urls: # in the selection there should be an error. I am not sure that I am selecting the rig
    print(u)
    url = 'https://www.urlvoid.com/scan/'+ u
    r = requests.get(url)
    ares.append(r)   

rows = []
cols = []

for ar in ares:
    soup = BeautifulSoup(ar.content, 'lxml')
    tab = soup.select("table.table.table-custom.table-striped")   
    try:
            dat = tab[0].select('tr')
            line= []
            header=[]
            for d in dat:
                row = d.select('td')
                line.append(row[1].text)
            new_header = row[0].text
            if not new_header in cols:
                cols.append(new_header)
            rows.append(line)
    except IndexError:
        continue

print(rows) # this works fine. It prints the rows. The issue comes from the next line

data_to_use = pd.DataFrame(rows,columns=cols)  

К сожалению, что-то не так в предыдущих шагах, так как я не получаю никаких результатов, но только [] или __.

Ошибка от data_to_use = pd.DataFrame(rows,columns=cols):

ValueError: 1 columns passed, passed data had 12 columns

Мой ожидаемый результат будет:

URL          Website Address   Last Analysis   Blacklist Status \  
bbc.co.uk          Bbc.co.uk         9 days ago       0/35
stackoverflow.com Stackoverflow.com  7 days ago      0/35

Domain Registration               IP Address       Server Location    ...
996-08-01 | 24 years ago       151.101.64.81    (US) United States    ...
2003-12-26 | 17 years ago      ...

В конце я должен сохранить набор данных, созданный в файле CSV.

Ответы [ 3 ]

2 голосов
/ 08 апреля 2020

Yon может сделать это, используя только pandas. Попробуйте следующий код.

urllist=[ 'bbc.co.uk','stackoverflow.com','who.int','cnn.com']

dffinal=pd.DataFrame()
for url in urllist:
    df=pd.read_html("https://www.urlvoid.com/scan/" + url + "/")[0]
    list = df.values.tolist()
    rows = []
    cols = []
    for li in list:
        rows.append(li[1])
        cols.append(li[0])
    df1=pd.DataFrame([rows],columns=cols)
    dffinal = dffinal.append(df1, ignore_index=True)

print(dffinal)
dffinal.to_csv("domain.csv",index=False)

Csv снимок:

enter image description here

Снимок.

enter image description here

CSV-файл.

enter image description here


Обновление с помощью блока try..except, так как часть URL не возвращает данные.

urllist=['gov.ie','','who.int', 'comune.staranzano.go.it', 'cooptrasportiriolo.it', 'laprovinciadicomo.it', 'asufc.sanita.fvg.it', 'canale7.tv', 'gradenigo.it', 'leggo.it', 'urbanpost.it', 'monitorimmobiliare.it', 'comune.villachiara.bs.it', 'ilcittadinomb.it', 'europamulticlub.com']

dffinal=pd.DataFrame()
for url in urllist:
    try:
        df=pd.read_html("https://www.urlvoid.com/scan/" + url + "/")[0]
        list = df.values.tolist()
        rows = []
        cols = []
        for li in list:
            rows.append(li[1])
            cols.append(li[0])
        df1=pd.DataFrame([rows],columns=cols)
        dffinal = dffinal.append(df1, ignore_index=True)

    except:
        continue

print(dffinal)
dffinal.to_csv("domain.csv",index=False)

Консоль :

            Website Address  ...         Region
0                     Gov.ie  ...         Dublin
1                    Who.int  ...         Geneva
2    Comune.staranzano.go.it  ...        Unknown
3      Cooptrasportiriolo.it  ...        Unknown
4       Laprovinciadicomo.it  ...        Unknown
5                 Canale7.tv  ...        Unknown
6                   Leggo.it  ...          Milan
7               Urbanpost.it  ...  Ile-de-France
8      Monitorimmobiliare.it  ...        Unknown
9   Comune.villachiara.bs.it  ...        Unknown
10          Ilcittadinomb.it  ...        Unknown

[11 rows x 12 columns]
1 голос
/ 09 апреля 2020

Отложив преобразование в csv, давайте попробуем это так:

urls=['gov.ie', 'who.int', 'comune.staranzano.go.it', 'cooptrasportiriolo.it', 'laprovinciadicomo.it', 'asufc.sanita.fvg.it', 'canale7.tv', 'gradenigo.it', 'leggo.it', 'urbanpost.it', 'monitorimmobiliare.it', 'comune.villachiara.bs.it', 'ilcittadinomb.it', 'europamulticlub.com']
ares = []
for u in urls:
    url = 'https://www.urlvoid.com/scan/'+u
    r = requests.get(url)
    ares.append(r)

Обратите внимание, что в 3 из URL нет данных, поэтому в кадре данных должно быть только 11 строк. Далее:

rows = []
cols = []
for ar in ares:
    soup = bs(ar.content, 'lxml')
    tab = soup.select("table.table.table-custom.table-striped")        
    if len(tab)>0:
        dat = tab[0].select('tr')
        line= []
        header=[]
        for d in dat:
            row = d.select('td')
            line.append(row[1].text)
            new_header = row[0].text
            if not new_header in cols:
                cols.append(new_header)
        rows.append(line)

my_df = pd.DataFrame(rows,columns=cols)   
my_df.info()

Вывод:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 11 entries, 0 to 10
Data columns (total 12 columns):
Website Address        11 non-null object
Last Analysis          11 non-null object
Blacklist Status       11 non-null object
Domain Registration    11 non-null object
Domain Information     11 non-null object
IP Address             11 non-null object
Reverse DNS            11 non-null object
ASN                    11 non-null object
Server Location        11 non-null object
Latitude\Longitude     11 non-null object
City                   11 non-null object
Region                 11 non-null object
dtypes: object(12)
memory usage: 1.2+ KB
0 голосов
/ 09 апреля 2020

Просто добавив к решению @ KunduK. Вы можете сжать часть этого кода, используя pandas '.T (функция транспонирования).

Таким образом, вы можете превратить эту часть:

df=pd.read_html("https://www.urlvoid.com/scan/" + url + "/")[0]
list = df.values.tolist()
rows = []
cols = []
for li in list:
    rows.append(li[1])
    cols.append(li[0])
df1=pd.DataFrame([rows],columns=cols)
dffinal = dffinal.append(df1, ignore_index=True)

в просто:

df=pd.read_html("https://www.urlvoid.com/scan/" + url + "/")[0].set_index(0).T
dffinal = dffinal.append(df, ignore_index=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...