Как извлечь элементы из скрипта html с BeautifulSoup - PullRequest
0 голосов
/ 10 октября 2018

Я новичок в программировании на Python, и я использую BeautifulSoup для того, чтобы сделать кое-какую очистку от избирательного отдела округа Чили.Моя проблема заключается в следующем: мне нужно извлечь конкретные строки из сценария.После некоторой очистки я получаю что-то вроде этого:

<script type="text/javascript">
    document.writeln("<p align='left' class='cleleccion2008'>");
    document.writeln("&nbsp;&nbsp;&nbsp;&nbsp;<a href='geografico.htm'>&laquo;&nbsp;&nbsp;VOLVER MEN&Uacute;<\/a><br>");
    document.writeln("<\/p>");
    document.writeln("<div class='mapTitle'>REGI&Oacute;N<\/div>");
    document.writeln("<p align='left' class='cleleccion2008'>");
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'101'+")' >Regi&oacute;n I<\/a><br>");
    document.writeln("<\/p>");
    document.writeln("<br>");
    document.writeln("<div class='mapTitle'>COMUNAS<\/div>");
    document.writeln("<p align='left' class='cleleccion2008'>"); 
    if ( parent.DIR_ANO >= "2004"){
        document.writeln("  &nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2307'+")' >Alto Hospicio<\/a> <br>");
    }
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2101'+")' >Arica<\/a><br>");
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2102'+")' >Camarones<\/a><br>");
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2303'+")' >Cami&ntilde;a<\/a><br>");
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2304'+")' >Colchane<\/a><br>");
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2202'+")' >General Lagos<\/a><br>");
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2302'+")' >Huara<\/a><br>");  
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2301'+")' >Iquique<\/a><br>");  
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2305'+")' >Pica<\/a><br>");
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2306'+")' >Pozo Almonte<\/a><br>");   
    document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2201'+")' >Putre<\/a><br>");                
    document.writeln("<\/p>"); 
    document.close();                                                               
}
</script>

Из этого скрипта я хочу извлечь из последних 12 строк название и код округа, чтобы создать что-то вроде:

Код, округ 2101, Арика 2102, Камаронес ... 2201, Путре

Любая помощь будет очень признательна.Спасибо за все ваши ответы / чтения.

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Джихан частично прав, в том смысле, что в явном виде BeautifulSoup нет синтаксических анализаторов javascript.Вам все еще, вероятно, понадобится bs4 для выполнения начального анализа.Регулярные выражения могут помочь вам разобраться со строками, но я бы использовал скомпилированное регулярное выражение вместо выполнения re.findall().Использование re.findall() может привести к множеству ложных срабатываний и очистке для вас.Если вы выполняете регулярное регулярное выражение, вы можете быть намного увереннее, что получаете правильные данные и выполняете проверку во время итерации.Это также в конечном итоге приводит к более чистому коду и более управляемому выводу.

Вместо этого вы можете явно вытянуть тег <script> из содержимого страницы и использовать метод str.splitlines() для нужного тега сценария.Это разделит весь тег на список строк.Возможно, вы захотите разбить символ ;, который обозначает завершение строки JavaScript, чтобы он работал даже в тех случаях, когда вы имеете дело с «оптимизированным» (запутанным) кодом JavaScript, который яростно разбит вместе.

В этот момент вы можете использовать скомпилированное (или простое re.search()) регулярное выражение в каждой строке.Таким образом, вы уверены, что вы получаете построчное соответствие.Вот код.

import argparse
import bs4
import re
import requests


def parse_county_codes(soup_object):
    for tag in soup_object:
        tag = str(tag)
        lines = tag.splitlines()
        code_regex = re.compile('"[+]\'(.*?)\'[+]"')
        county_regex = re.compile('\'[ ]>(.*?)<')

        for line in lines:
            county = county_regex.search(line)
            code = code_regex.search(line)
            if county and code:
                print(county.group(1), ':', code.group(1))

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--input-file', dest='in_file', help='Input html')
    parser.add_argument('-u', '--url', dest='url', help='Some url\'s content you want to parse')
    args = parser.parse_args()

    if args.in_file:
        with open(args.in_file) as f:
            html_string = f.read()
            soup = bs4.BeautifulSoup(html_string, 'html.parser')
    elif args.url:
        try:
            # Remember to handle any possible url handling exceptions
            response = requests.get(args.url)
        except Exception as e:
            print("The following exception occurred while requesting the url\n{0}".format(args.url))
            print(e)
            return

        soup = bs4.BeautifulSoup(response.content, 'html.parser')
    else:
        print("Input missing. Please provide -i or -u")
        return

    script_tags = soup.find_all('script')
    parse_county_codes(script_tags)

if __name__ == '__main__':
    main()

Вывод этого кода следующий:

Regi&oacute;n I : 101
Alto Hospicio : 2307
Arica : 2101
Camarones : 2102
Cami&ntilde;a : 2303
Colchane : 2304
General Lagos : 2202
Huara : 2302
Iquique : 2301
Pica : 2305
Pozo Almonte : 2306
Putre : 2201

Обратите внимание, что есть некоторые символы и escape-последовательности для специальных символов, которые выглядят неуместно встроки, но регулярные выражения в их текущей форме, предоставленные Jihan, действительны.Если вы хотите очистить вывод, вы лучше знаете, как это сделать, поэтому я оставлю это на ваше усмотрение.Помните, что ваш пробег может отличаться при использовании регулярных выражений, и в зависимости от содержимого других веб-страниц вы можете столкнуться с другими проблемами.

0 голосов
/ 10 октября 2018

Нет конкретного js parser в BeautifulSoup, но его можно легко обработать, используя regex.

import re

text = '''
<script type="text/javascript">
    document.writeln("<p align='left' class='cleleccion2008'>");
    document.writeln("&nbsp;&nbsp;&nbsp;&nbsp;<a 
href='geografico.htm'>&laquo;&nbsp;&nbsp;VOLVER MEN&Uacute;<\/a><br>");
document.writeln("<\/p>");
document.writeln("<div class='mapTitle'>REGI&Oacute;N<\/div>");
document.writeln("<p align='left' class='cleleccion2008'>");
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'101'+")' >Regi&oacute;n I<\/a><br>");
document.writeln("<\/p>");
document.writeln("<br>");
document.writeln("<div class='mapTitle'>COMUNAS<\/div>");
document.writeln("<p align='left' class='cleleccion2008'>"); 
if ( parent.DIR_ANO >= "2004"){
    document.writeln("  &nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2307'+")' >Alto Hospicio<\/a> <br>");
}
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2101'+")' >Arica<\/a><br>");
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2102'+")' >Camarones<\/a><br>");
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2303'+")' >Cami&ntilde;a<\/a><br>");
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2304'+")' >Colchane<\/a><br>");
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2202'+")' >General Lagos<\/a><br>");
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2302'+")' >Huara<\/a><br>");  
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2301'+")' >Iquique<\/a><br>");  
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2305'+")' >Pica<\/a><br>");
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2306'+")' >Pozo Almonte<\/a><br>");   
document.writeln("  &nbsp;&nbsp;&bull;&nbsp;<a href='javascript:Consulta("+'2201'+")' >Putre<\/a><br>");                
document.writeln("<\/p>"); 
document.close();                                                               
}
</script>
'''

result_num = []
result_county = []
result = []

for i in re.findall('"[+]\'(.*?)\'[+]"', text):
    result_num.append(i)
for j in re.findall('\'[ ]>(.*?)<', text):
    if j != '':
        result_county.append(j)

result_county = result_county[2:]
result_num = result_num[2:]

for count in range(len(result_county)):
    result.append(result_county[count] + result_num[count])

print(result)

Выход :

['Arica2101', 'Camarones2102', 'Cami&ntilde;a2303', 'Colchane2304', 'General Lagos2202', 'Huara2302', 'Iquique2301', 'Pica2305', 'Pozo Almonte2306', 'Putre2201']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...