如何使用Web抓取和Beautiful Soup构建数据框

时间:2020-08-21 12:28:52

标签: python pandas beautifulsoup

我正在尝试获取https://subastas.boe.es上的所有表并将它们传递给DataFrame。每个查询包含一个结果列表,每个结果具有一个选项卡列表,选项卡“ Lotes”包含一个项列表(每个项都有两个表)。

首先,我获得了所有结果ID(auction_id):

在:

soup = BeautifulSoup(requests.get(URL).text, 'lxml')

auction_idx = []

for auction in soup.find_all('h3'):
    auction_idx.append(auction.text)
        
auction_idx = list(map(lambda x: x.replace("SUBASTA ", "").replace('\n', '').replace(' ', '').strip(), auction_idx))

auction_id = []

for x in auction_idx:
    a = re.sub(r'\(.*\)', '', x)
    auction_id.append(a)

auction_id

出局:

['SUB-JA-2017-60716',
 'SUB-JA-2019-138189',
 'SUB-JA-2019-123312',
 'SUB-JA-2019-140424',
 'SUB-JA-2019-134590',
 'SUB-JA-2019-138691',
 'SUB-JA-2019-140415',
...]

第二,我得到每个结果的所有URL(url_list):

在:

url_auction = []

for auction in auction_id:
    url_auction.append('https://subastas.boe.es/detalleSubasta.php?idSub=' + auction + '&ver=3')

# For each auction_id I find all the URLs (tabs and items).

url_list = []

for url in url_auction:
    soup = BeautifulSoup(requests.get(url).text, 'lxml')
    for link in soup.find_all('a', href=re.compile('detalleSubasta')):
        url_list.append(link.get('href'))

# Adding the complete URL

url_list = list(map(lambda x: x.replace("./detalleSubasta", "https://subastas.boe.es/detalleSubasta"), url_list))

出局:

url_list = 
['https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2019-140415&ver=1&idBus=&idLote=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2019-140415&ver=2&idBus=&idLote=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2019-140415&ver=3&idBus=&idLote=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2019-140415&ver=4&idBus=&idLote=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2019-140415&ver=5&idBus=&idLote=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2019-140415&ver=3&idLote=1&idBus=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2019-140415&ver=3&idLote=2&idBus=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2019-140415&ver=3&idLote=3&idBus=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2020-142911&ver=1&idBus=&idLote=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2020-142911&ver=2&idBus=&idLote=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2020-142911&ver=3&idBus=&idLote=&numPagBus=',
 'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2020-142911&ver=5&idBus=&idLote=&numPagBus=',
...]

然后,我得到一个包含Auction_id,标签名,URL和表的列表列表(全部):

在:

data = []

for url in url_list:
    soup = BeautifulSoup(requests.get(url).text, 'lxml')
    for table in soup.find_all('table'):
        for auction in soup.find_all('h2'):
            for tab in soup.find("label", {"class": "selected"}):
                data.append([auction.text.replace('Subasta ', ''), tab, url, pd.read_html(str(table))]) # incluir cada auction_id, url y tabla en una lista

data

出局:

[['SUB-JA-2017-60716',
  'Información general',
  'https://subastas.boe.es/detalleSubasta.php?idSub=SUB-JA-2017-60716&ver=1&idBus=&idLote=&numPagBus=',
  [                       0                                                  1
   0          Identificador                                  SUB-JA-2017-60716
   1        Tipo de subasta                         JUDICIAL EN VIA DE APREMIO
   2        Fecha de inicio  31-01-2020 18:00:00 CET (ISO: 2020-01-31T18:00...
   3    Fecha de conclusión  20-02-2020 18:00:00 CET (ISO: 2020-02-20T18:00...
   4     Cantidad reclamada                                       278.512,71 €
   5                  Lotes                                          Sin lotes
   6            Anuncio BOE                                    BOE-B-2020-3581
   7          Valor subasta                                       369.700,00 €
   8               Tasación                                          No consta
   9            Puja mínima                                    Sin puja mínima
   10    Tramos entre pujas                                         Sin tramos
   11  Importe del depósito                                        18.485,00 €]],
...]

好吧,在这一点上,我对结果感到非常满意,但是,我绝对无法解决的问题是,对列表列表进行迭代以在DataFrame中为每个Auction_id获取一行的操作;考虑到对于每个带有“ Lotes”的Auction_id,我必须复制该行,并替换第一个表的“ Lotes”选项卡的值,然后添加第二个表。

然后,我必须在列轴中添加带有标签名称的Multiindex,并添加每个标签的URL。

首先,我用列初始化一个空的DataFrame:

在:

array0 = [['Información general'], ['Identificador', 'Tipo de subasta', 'Fecha de inicio', 'Fecha de conclusión',
                                    'Cantidad reclamada', 'Lotes', 'Forma adjudicación', 'Anuncio BOE', 'Valor subasta', 
                                    'Tasación', 'Puja mínima', 'Tramos entre pujas', 'Importe del depósito', 
                                    'Información complementaria']]
array1 = [['Autoridad gestora'], ['Código', 'Descripción', 'Dirección', 'Teléfono', 'Fax', 'Correo electrónico']]
array2 = [['Bienes'], ['Descripción', 'IDUFIR', 'Referencia catastral', 'Dirección', 'Código postal', 'Localidad', 'Provincia', 'Vivienda habitual', 'Situación posesoria', 
                       'CSV Certificación registral', 'Información registral electrónica', 'Visitable', 'Cargas', 
                       'Inscripción registral', 'Información adicional', 'Matrícula', 'Marca']]
array3 = [['Relacionados'], ['Nombre', 'NIF', 'Dirección', 'Localidad', 'Provincia', 'País']]
array4 = [['Pujas'], ['Puja más alta', 'Mis pujas', 'Tiempo restante de la subasta', 'Certificado de cierre']]

df = pd.DataFrame(columns = pd.MultiIndex.from_product(array4, names= ['Página','Campo']))

df = df.append(pd.DataFrame(columns = pd.MultiIndex.from_product(array3, names= ['Página','Campo'])), ignore_index = True, sort = False)

df = df.append(pd.DataFrame(columns = pd.MultiIndex.from_product(array2, names= ['Página','Campo'])), ignore_index = True, sort = False)

df = df.append(pd.DataFrame(columns = pd.MultiIndex.from_product(array1, names= ['Página','Campo'])), ignore_index = True, sort = False)

df = df.append(pd.DataFrame(columns = pd.MultiIndex.from_product(array0, names= ['Página','Campo'])), ignore_index = True, sort = False)

df

出局:

DataFrame

这是我主要的疑问,我真正需要帮助的是

  1. 如何遍历列表中的数组(数据框)以便在所有表中添加auction_id。
  2. 如何也将URL添加到每个表中。
  3. 如何在每个表的列轴中将选项卡名称添加为Multiindex。
  4. 如何遍历列表以使用相同的auction_id连接表,并将它们作为一行传递给DataFrame。

在堆栈溢出和编程方面,我是全新的,我不知道我是否正确提出了问题。任何有关这方面的指导都会对我有所帮助。

谢谢

0 个答案:

没有答案