Вытащить только последний элемент из тега в BeautifulSoup - PullRequest
0 голосов
/ 20 мая 2018

У меня есть скрипт, который просматривает несколько веб-страниц, но есть одна маленькая проблема, на которой я застрял.Я пытаюсь добавить автора в список, но мой скрипт извлекает последнего автора со страницы и применяет его к каждому полю автора.Как мне заставить мой сценарий применить каждого автора к соответствующему названию?Вот мой код

from urllib.request import urlopen
from bs4 import BeautifulSoup as soup
import json

base_url = "https://archive.org/details/librivoxaudio?&sort=titleSorter"

data = []
n = 5
for i in range(1, n+1):
   response = urlopen(base_url + "&page=" + str(i))
   page_html = response.read()
   response.close()

   #html parsing
   page_soup = soup(page_html, "html.parser")

   #grabs info for each book
   containers = page_soup.findAll("div",{"class":"item-ttl"})
   authors = page_soup.findAll("span",{"class":"byv"})

   for container in containers:
     item = {}
     item['type'] = "Public Domain Audiobook"
     item['title'] = container.text.lstrip().strip()
     for author in authors:
         item['author'] = author.text
     item['link'] = "https://archive.org/" + container.a["href"]
     item['source'] = "LibriVox"
     item['base_url'] = "https://librivox.org/"
     data.append(item) # add the item to the list

     with open("./json/librivoxTest.json", "w") as writeJSON:
       json.dump(data, writeJSON, ensure_ascii=False)

Вот пример выходных данных в JSON

{
"type": "Public Domain Audiobook",
"title": "A Book of Old English Ballads",
"author": "Charles Whibley",
"link": "https://archive.org//details/book_old_english_ballads_1007_librivox",
"source": "LibriVox",
"base_url": "https://librivox.org/"
}, {
"type": "Public Domain Audiobook",
"title": "A Book of Scoundrels",
"author": "Charles Whibley",
"link": "https://archive.org//details/scoundrels_1712_librivox",
"source": "LibriVox",
"base_url": "https://librivox.org/"
}

Последний автор подходит для «Книги негодяев», но «Книги древнеанглийскогоУ Баллады должен быть Джордж Уортон Эдвардс в качестве автора.

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Полагаю, что приведенный ниже скрипт исправит возникшие проблемы.Я попытался сделать это немного организованным образом.

from urllib.request import urlopen
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import json

urls = ["https://archive.org/details/librivoxaudio?&sort=titleSorter&page={}".format(page) for page in range(1,3)]

for link in urls:
    soup = BeautifulSoup(urlopen(link).read(), "html.parser")
    data = []
    for container in soup.select("div[data-id$='_librivox']"):
         item = {}
         item['type'] = "Public Domain Audiobook"
         item['title'] = container.select_one(".ttl").get_text(strip=True)
         item['author'] = container.select_one(".byv").get_text(strip=True) if container.select_one(".byv") else ""
         item['link'] = urljoin(link, container.select_one("a[title]")['href']) if container.select_one("a[title]") else ""
         item['source'] = "LibriVox"
         item['base_url'] = "https://librivox.org/"
         data.append(item)

    print(json.dumps(data,indent=4))

Вывод похож на:

[
    {
        "type": "Public Domain Audiobook",
        "title": "\"BOOH!\"",
        "author": "Eugene Field",
        "link": "https://archive.org/details/booh_1403.poem_librivox",
        "source": "LibriVox",
        "base_url": "https://librivox.org/"
    },
    {
        "type": "Public Domain Audiobook",
        "title": "\"You Bid Me Try\"",
        "author": "Henry Austin Dobson",
        "link": "https://archive.org/details/youbid_metry_1104_librivox",
        "source": "LibriVox",
        "base_url": "https://librivox.org/"
    },
0 голосов
/ 20 мая 2018

for author in authors: item['author'] = author.text

Это проходит по всем авторам и устанавливает их как автора элемента.Последний автор будет установлен для элемента в конце.

Чтобы установить вместо него соответствующего автора, используйте генератор для авторов (authors_iterator = iter(authors), затем для элемента установите next(authors_iterator)) илииспользуйте enumerate для циклического перемещения по контейнерам и используйте его индекс для авторов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...