Невозможно очистить данные в теге <li>, имеющем более одного тега <a>из секции преобразования википедии. - PullRequest
0 голосов
/ 24 сентября 2018

Я хочу получить имена героев фильма из раздела «Каст» на странице ниже википедии.Я не могу получить некоторые имена из-за большого количества якорных элементов в одном теге <li>.

Sample- Первая строка:

"Том Круз в роли Итана Ханта, МВФагент и руководитель группы оперативников "

  1. Я хочу только имена (Результат: Итан Хант), которые идут после слова" как "
  2. А также, я хочу предложения, которыепосле запятой (Результат: агент МВФ и руководитель группы оперативников)

url: https://en.wikipedia.org/wiki/Mission:Impossible%E2%80%93_Fallout

Вот мой код ниже (извините за длинный код):

html = requests.get('https://en.wikipedia.org/wiki/Mission:_Impossible_%E2%80%93_Fallout', verify=False).text
soup = BeautifulSoup(html, 'lxml')
cast_tag = soup.find('span',{'id':'Cast'}).parent
s = soup.findAll('h2')
persons = []
roles = []
for i in s:
    if i == cast_tag:
        cast_sibling =  i.findNextSiblings()[0]
        for li in cast_sibling.find_all('li'):
            li_string = li.string
            a_tags_in_li = li.find_all('a')

            if li_string != None:
                if li_string.find('as') >= 0:
                    if li_string.find(','):    
                        st = "".join(li_string[li_string.find('as')+2:li_string.find(',')]).strip()
                        persons.append(st)
                        role = "".join(li_string[li_string.find(',')+1:len(li_string)]).strip()
                        roles.append({st:role})
                    else:
                        st = "".join(li_string[li_string.find('as')+2:len(li_string)]).strip()
                        persons.append(st)
            elif a_tags_in_li:
                lst = [a.string for a in a_tags_in_li]
                if len(lst) > 1 and not re.search(regex, lst[1]):
                    if lst[1].find('as') >= 0:
                        if li_string.find(','):
                            st = "".join(lst[1][lst[1].find('as')+2:len(lst[1])]).strip()
                            persons.append(st)
                            role = "".join(li_string[li_string.find(',')+1:len(li_string)]).strip()
                            roles.append({st:role})
                    else:
                        persons.append(lst[1])

                elif not re.search(r"[[\]]", lst[0]):
                    if lst[0].find('as') >= 0:
                        st = "".join(lst[0][lst[0].find('as')+2:len(lst[0])]).strip()
                        persons.append(st)
                    else:
                        persons.append(lst[0])

1 Ответ

0 голосов
/ 25 сентября 2018

Я бы немного очистил этот код ... пытаясь быть немного более питоническим;)

import re
import requests
from bs4 import BeautifulSoup

persons = []
roles = {}

html = requests.get('https://en.wikipedia.org/wiki/Mission:_Impossible_%E2%80%93_Fallout', verify=False).text
soup = BeautifulSoup(html, 'lxml')
cast_tag = soup.find('span',{'id':'Cast'}).parent
cast_sibling = cast_tag.findNextSiblings()[0]

for li in cast_sibling.find_all('li'):
    # just get the text, forget about tags
    li_string = li.get_text()

    if li_string != None and 'as' in li_string:
        # break at comma into max 2 strings
        string_parts = li_string.split(',', 1)

        # handle name part, before comma
        name_part = string_parts[0]

        # get name after ' as ', keep spaces to prevent issues with names like 'Bassett'
        st = name_part[name_part.find(' as ')+3:].strip()
        persons.append(st)

        # if there is anything after the comma, add it to dictionary
        if len(string_parts) > 1:
            roles[st] = string_parts[1].strip()

for person in persons:
    print(person + ': ' + roles.get(person,''))
...