как сделать очистку информации, разбитой на блоки? - PullRequest
0 голосов
/ 12 апреля 2019

В python3 мне нужно выполнить очистку сайта

Каждый запрос на сайте генерирует серию информации, которую я хочу захватить:

1 -номер юридического процесса,

2 - тип процесса (пример - Procedimento Comum Cível / Indenização por Dano Moral),

3 - строка 'Reqdo:' или 'Reqte:',

4 - соответствующее имя (пример - Google Brasil Internet Ltda),

5 - дата

6 - местоположение процесса (пример - 9ª Vara de Fazenda Pública)

Для этого я выделил блок, в котором информация о юридических процессах имеет вид

from bs4 import BeautifulSoup
import requests

link = 'https://esaj.tjsp.jus.br/cpopg/search.do?conversationId=&dadosConsulta.localPesquisa.cdLocal=-1&cbPesquisa=NMPARTE&dadosConsulta.tipoNuProcesso=UNIFICADO&dadosConsulta.valorConsulta=Google&uuidCaptcha=&pbEnviar=Pesquisar'

try:
    res = requests.get(link, verify=False) # I ignore SSLError just this case
except (requests.exceptions.HTTPError, requests.exceptions.RequestException, requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
    print(str(e))
    return 
except Exception as e:
    print("Exception")
    return

soup =  BeautifulSoup(res.text, "lxml")

bloco = soup.find_all('div', {'id': 'listagemDeProcessos'})

Содержимое блока: первые строки:

[<div id="listagemDeProcessos">
<div style="padding:0px 10px;">
<div class="">
<br/>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr valign="top">
<td background="/cpopg/imagens/spw/fundo_subtitulo.gif" height="21" nowrap="" valign="top">
<h2 class="subtitle">
                        Foro Central - Fazenda Pública/Acidentes

                    </h2>
</td>
<td aria-hidden="true" background="/cpopg/imagens/spw/fundo_subtitulo2.gif" width="90%">
<img height="20" src="/cpopg/imagens/spw/final_subtitulo.gif" tabindex="-1" width="16"/>
</td>
</tr>
</table>
<br/>
<table border="0" cellpadding="2" cellspacing="0" class="secaoFormBody" id="" style="" width="100%">
</table>
</div>
</div>
<div class="fundoClaro" id="divProcesso2S000X02D0000" style="margin-left: 10px; margin-top: 0px;">
<div class="fundoClaro">
<div class="nuProcesso">
<!-- Atributos -->
<a class="linkProcesso" href="/cpopg/show.do?processo.codigo=2S000X02D0000&amp;processo.foro=53&amp;paginaConsulta=1&amp;conversationId=&amp;dadosConsulta.localPesquisa.cdLocal=-1&amp;cbPesquisa=NMPARTE&amp;dadosConsulta.tipoNuProcesso=UNIFICADO&amp;dadosConsulta.valorConsulta=Google&amp;uuidCaptcha=&amp;pbEnviar=Pesquisar">
            1094431-73.2018.8.26.0100   
        </a>
<span class="">
</span>
</div>                    
    Procedimento Comum Cível <b>/</b> Indenização por Dano Moral 
    <br/>
<div class="espacamentoLinhas">
<span style="font-weight: bold">Reqdo:</span>
            Google Brasil Internet Ltda

        </div>
<div class="espacamentoLinhas">
<span style="font-weight: bold">Recebido em:</span>
        11/09/2018 - 9ª Vara de Fazenda Pública
    </div>
</div>
</div>
<div class="fundoEscuro" id="divProcesso1H00079DG0000" style="margin-left: 10px; margin-top: 12px;">
<div class="fundoEscuro">
<div class="nuProcesso">
<!-- Atributos -->
<a class="linkProcesso" href="/cpopg/show.do?processo.codigo=1H00079DG0000&amp;processo.foro=53&amp;paginaConsulta=1&amp;conversationId=&amp;dadosConsulta.localPesquisa.cdLocal=-1&amp;cbPesquisa=NMPARTE&amp;dadosConsulta.tipoNuProcesso=UNIFICADO&amp;dadosConsulta.valorConsulta=Google&amp;uuidCaptcha=&amp;pbEnviar=Pesquisar">
            1045899-54.2014.8.26.0053   
        </a>
<span class="">
</span>
</div>                    
    Procedimento Comum Cível <b>/</b> Crédito Tributário 
    <br/>
<div class="espacamentoLinhas">
<span style="font-weight: bold">Reqte:</span>
            Google Brasil Internet Ltda.

        </div>
<div class="espacamentoLinhas">
<span style="font-weight: bold">Recebido em:</span>
        31/10/2014 - 10ª Vara de Fazenda Pública
    </div>
</div>
</div>
<div class="fundoClaro" id="divProcesso1H00020270000" style="margin-left: 10px; margin-top: 12px;">
<div class="fundoClaro">
<div class="nuProcesso">

Iзаметил, что все блоки информации разделены строкой '<!-- Atributos -->'

Можно ли это также считать тегом?

Одной из стратегий, которые я думал захватить блоки информации, было захватить все, что имеетстрока '<!-- Atributos -->'

А затем итерировать их иизвлечь интересующую информацию

Что имеет смысл?Пожалуйста, как я мог это сделать?

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

BeautifulSoup 4.7+ использует библиотеку выбора под названием Soup Sieve, которая установлена ​​рядом с BeautifulSoup.Вы можете импортировать его напрямую и создать шаблоны соответствия селектора CSS:

import soupsieve as sv

# Create CSS patterns to find data that we want to capture
legal_process = sv.compile('div.nuProcesso')
info1 = sv.compile('br + div.espacamentoLinhas')
info2 = sv.compile('div.espacamentoLinhas + div.espacamentoLinhas')

Тип процесса не заключен в элемент, который легко нацеливается, но соответствует номеру процесса, поэтому мы можем создать простую функцию для извлечениятекст сразу после него, пока мы не нажмем следующую div:

def get_process_type(el):
    # Text is found right after this child, so gather text until we hit next div
    text = []
    sibling = el.next_sibling
    while True:
        if isinstance(sibling, NavigableString):
            text.append(sibling)
        elif isinstance(sibling, Tag):
            if sibling.name == 'div':
                break
            text.append(sibling.text)
        sibling = sibling.next_sibling
    return ''.join(text).strip().replace('\xa0', '')

Тогда мы можем собрать все это вместе.Здесь мы в основном нацеливаемся на все дочерние элементы div с идентификатором listagemDeProcessos, а затем сопоставляем каждого дочернего элемента и обрабатываем извлечение данных для каждого.Каждый раз, когда мы находим номер процесса, мы начинаем новую запись в нашем списке:

from bs4 import BeautifulSoup, Tag, NavigableString
import soupsieve as sv
import requests
import re

link = 'https://esaj.tjsp.jus.br/cpopg/search.do?conversationId=&dadosConsulta.localPesquisa.cdLocal=-1&cbPesquisa=NMPARTE&dadosConsulta.tipoNuProcesso=UNIFICADO&dadosConsulta.valorConsulta=Google&uuidCaptcha=&pbEnviar=Pesquisar'

try:
    res = requests.get(link, verify=False) # I ignore SSLError just this case
except (requests.exceptions.HTTPError, requests.exceptions.RequestException, requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
    print(str(e))
except Exception as e:
    print("Exception")

soup =  BeautifulSoup(res.text, "lxml")

# Create CSS patterns to find data that we want to capture
legal_process = sv.compile('div.nuProcesso')
info1 = sv.compile('br + div.espacamentoLinhas')
info2 = sv.compile('div.espacamentoLinhas + div.espacamentoLinhas')
date_split = re.compile(r'-\s+(?:\d+\xaa)?')

def get_process_type(el):
    # Text is found right after this child, so gather text until we hit next div
    text = []
    sibling = el.next_sibling
    while True:
        sibling = sibling.next_sibling
        if isinstance(sibling, NavigableString):
            text.append(sibling)
        elif isinstance(sibling, Tag):
            if sibling.name == 'div':
                break
    return ''.join(text).strip()

records = []

for child in soup.select('div#listagemDeProcessos *'):
    if legal_process.match(child):
        # Store process number
        records.append({"process": child.text.strip()})

        # Store process type
        records[-1]['type'] = get_process_type(child)

    elif info1.match(child):
        # Store required label and name
        records[-1]['label'], records[-1]['name'] = [item.strip() for item in child.text.split(':', 1)]
    elif info2.match(child):
        # Store date and location
        print(child.text)
        records[-1]['date'], records[-1]['location'] = [item.strip() for item in date_split.split(child.text.split(':', 1)[1], 1)]

print(records)

Выход

[{'process': '1045899-54.2014.8.26.0053', 'type': 'Procedimento Comum Cível/Crédito Tributário', 'label': 'Reqte', 'name': 'Google Brasil Internet Ltda.', 'date': '31/10/2014', 'location': 'Vara de Fazenda Pública'}, {'process': '0023942-53.2010.8.26.0053   \n\t\t\n\n\t\t\t(053.10.023942-3)', 'type': 'Procedimento Comum Cível/Indenização por Dano Material', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '20/07/2010', 'location': 'Vara de Fazenda Pública'}, {'process': '1094431-73.2018.8.26.0100', 'type': 'Procedimento Comum Cível/Indenização por Dano Moral', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '11/09/2018', 'location': 'Vara Cível'}, {'process': '1030857-42.2019.8.26.0100', 'type': 'Liquidação por Arbitramento/Valor da Execução / Cálculo / Atualização', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '05/04/2019', 'location': 'Vara Cível'}, {'process': '1030497-10.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Práticas Abusivas', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '05/04/2019', 'location': 'Vara Cível'}, {'process': '1030110-92.2019.8.26.0100', 'type': 'Ação Civil Pública Cível/Prestação de Serviços', 'label': 'Reqdo', 'name': 'Empresa Controladora do Site Google', 'date': '04/04/2019', 'location': 'Vara Cível'}, {'process': '1028847-25.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Direito de Imagem', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '01/04/2019', 'location': 'Vara Cível'}, {'process': '1028109-37.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Direito de Imagem', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '29/03/2019', 'location': 'Vara Cível'}, {'process': '1027277-04.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Direito de Imagem', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '27/03/2019', 'location': 'Vara Cível'}, {'process': '1026784-27.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Direito de Imagem', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda.', 'date': '27/03/2019', 'location': 'Vara Cível'}, {'process': '1067163-47.2018.8.26.0002', 'type': 'Procedimento Comum Cível/Atos Unilaterais', 'label': 'Reqte', 'name': 'Google Brasil Internet Ltda', 'date': '19/12/2018', 'location': 'Vara Cível'}, {'process': '0017668-14.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Obrigação de Fazer / Não Fazer', 'label': 'Reqdo', 'name': 'Google Brasil Internet LTDA', 'date': '22/03/2019', 'location': 'Vara Cível'}, {'process': '1010443-26.2019.8.26.0002', 'type': 'Procedimento Comum Cível/Marca', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '28/02/2019', 'location': 'VARA EMPRESARIAL E CONFLITOS DE ARBITRAGEM'}, {'process': '1019636-62.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Marca', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda.', 'date': '07/03/2019', 'location': 'Vara Cível'}, {'process': '1019227-86.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Direito de Imagem', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda.', 'date': '06/03/2019', 'location': 'Vara Cível'}, {'process': '1018870-09.2019.8.26.0100', 'type': 'Embargos de Terceiro Cível/Constrição / Penhora / Avaliação / Indisponibilidade de Bens', 'label': 'Embargdo', 'name': 'Google Brasil Internet LTDA', 'date': '04/03/2019', 'location': 'Vara Cível'}, {'process': '1017903-61.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Defeito, nulidade ou anulação', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '28/02/2019', 'location': 'Vara Cível'}, {'process': '1017420-31.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Direito Autoral', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '27/02/2019', 'location': 'Vara Cível'}, {'process': '1016588-95.2019.8.26.0100', 'type': 'Produção Antecipada da Prova/Provas', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda.', 'date': '26/02/2019', 'location': 'Vara Cível'}, {'process': '1015924-64.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Propriedade Intelectual / Industrial', 'label': 'Reqdo', 'name': 'Google Internet Brasil Ltda', 'date': '22/02/2019', 'location': 'VARA EMPRESARIAL E CONFLITOS DE ARBITRAGEM'}, {'process': '1015478-61.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Direito de Imagem', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '22/02/2019', 'location': 'Vara Cível'}, {'process': '1015189-31.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Direito de Imagem', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda.', 'date': '21/02/2019', 'location': 'Vara Cível'}, {'process': '1012927-11.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Direito de Imagem', 'label': 'Reqdo', 'name': 'Google Brasil Internet Ltda', 'date': '15/02/2019', 'location': 'Vara Cível'}, {'process': '1011615-97.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Direito de Imagem', 'label': 'Reqdo', 'name': 'Google Internet Brasil Ltda', 'date': '12/02/2019', 'location': 'Vara Cível'}, {'process': '1011601-16.2019.8.26.0100', 'type': 'Procedimento Comum Cível/Marca', 'label': 'Reqdo', 'name': 'Google Internet Brasil Ltda', 'date': '12/02/2019', 'location': 'Vara Cível'}]

РЕДАКТИРОВАТЬ: Исправлена ​​функция get_process_type.

1 голос
/ 12 апреля 2019

Вы можете получить bloco , используя селектор div[id^=divProcesso], что означает, что div с id начинается с divProcesso .

blocos = soup.select("div[id^=divProcesso]")
for bloco in blocos:
    number = bloco.find('a', {'class': 'linkProcesso'}).text.strip()
    process_type = "/".join(bloco.select_one("div.nuProcesso")
                            .find_next_siblings(text=True)).strip()

    reqdo = ""
    reqte = ""
    espacamentoLinhas = bloco.select(".espacamentoLinhas")
    if "Reqdo:" in espacamentoLinhas[0].text:
        reqdo = espacamentoLinhas[0].text.replace("Reqdo:", "").strip()
    else:
        reqte = espacamentoLinhas[0].text.replace("Reqte:", "").strip()

    recebido_em = espacamentoLinhas[1].text.replace("Recebido em:", "").strip().split("-", maxsplit=1)
    recebido_em_date = recebido_em[0].strip()
    recebido_em_location = recebido_em[1].strip()
...