BeautifulSoup находит детей только с точкой, без функции find () - PullRequest
1 голос
/ 28 марта 2020

Я пытаюсь инициировать указанный элемент c в переменную, без использования функции 'find ()' или findAll () ', только с BeautifulSoup и' dots '. Что меня смущает, так это порядок приоритетов. Существует много вопросов «нахождения детей» с использованием функции findAll (), но, похоже, нет «точечных» вещей. Итак, наконец, я пишу этот вопрос.

Вот пример.

----- html ------

<div class="item-container">
    <!--product image-->
    <a class="item-img" href="https://www.newegg.com/asus-geforce-rtx-2080-ti-dual-rtx2080ti-o11g/p/N82E16814126247?Item=N82E16814126247">
        <div class="item-badges">
            <div class= "item-test">
             </div>
        </div>
        <img alt="ASUS Dual GeForce RTX 2080 Ti DirectX 12 DUAL-RTX2080TI-O11G 11GB 352-Bit GDDR6 PCI Express 3.0 HDCP Ready SLI Support Video Card" class="lazy-img" data-effect="fadeIn" data-src="//c1.neweggimages.com/NeweggImage/ProductImageCompressAll300/14-126-247-V50.jpg" src="//c1.neweggimages.com/WebResource/Themes/2005/Nest/blank.gif" title="ASUS Dual GeForce RTX 2080 Ti DirectX 12 DUAL-RTX2080TI-O11G 11GB 352-Bit GDDR6 PCI Express 3.0 HDCP Ready SLI Support Video Card">
        </img>
    </a>
    <div class="item-info">
        <!--brand info-->
        <div class="item-branding">
            <a class="item-brand" href="https://www.newegg.com/ASUS/BrandStore/ID-1315">
                <img alt="ASUS" class="lazy-img" data-effect="fadeIn" data-src="//c1.neweggimages.com/Brandimage_70x28//Brand1315.gif" src="//c1.neweggimages.com/WebResource/Themes/2005/Nest/blank.gif" title="ASUS">
                </img></a>
            <!--rating info-->
            <a class="item-rating" href="https://www.newegg.com/asus-geforce-rtx-2080-ti-dual-rtx2080ti-o11g/p/N82E16814126247?Item=N82E16814126247&amp;SortField=0&amp;SummaryType=0&amp;PageSize=10&amp;SelectedRating=-1&amp;VideoOnlyMark=False&amp;IsFeedbackTab=true#scrollFullInfo" title="Rating + 2"><i class="rating rating-2"></i><span class="item-rating-num">(32)</span></a>
        </div>
</div>
</div>

---- - python --------

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

my_url = "https://www.newegg.com/Video-Cards-Video-Devices/Category/ID-38?Tpk=graphic%20card"
uClient = uReq(my_url)
page_html = uClient.read() 
uClinet.close()
page_soup = soup(page_html, "html.parser")

отсюда, я найду div с классом 'брендинг предметов'. так я и пошел вот так

>>> page_soup.div.div

Что вы получаете от этого? Кажется, это зависит от версии python или чего-то еще. Это варьируется среди пользователей.

кто-то получает, но я получил ''. Видите ли вы эту разницу?

Первый (который получил) получает div среди детей первого уровня. Класс div 'item-badges' является дочерним по отношению к потомку a (класс 'item img'), так что это дочерний элемент второго уровня. Таким образом, заклинание «page_soup.div» пропустило div (элемент-брендинг) в первом «a (item-image)» и было поймано как первый «div». И поэтому «page_soup.div.div» может попасть прямо в «div class =« item-брендинг »».

Однако, во-вторых, мой компьютер не делает то же самое с тем же заклинанием .

мое заклинание 'page_soup.div.div' обнаружило 'div class = "item-test"'. Мое заклинание "page_soup.div" попало в ближайший div сверху, не касаясь уровня детей. Он только что попал в первый div, который находится внутри дочернего элемента 'a (class item-badges)'. Таким образом, page_soup.div.div попал в div div = «item-test», первый div в item-badges.

То же заклинание, но разные логики c.

Знаете ли вы, что делает эту разницу? И как это исправить?

Спасибо, гений.

ps я использую python 3.7 32x

1 Ответ

1 голос
/ 28 марта 2020

То, что вы спрашиваете, хорошо задокументировано здесь: BS: навигация с использованием имен тегов

Самый простой способ навигации по дереву разбора - это сказать имя тега, который вы хотите , Если вам нужен тег <head>, просто скажите soup.head.

. Вы можете использовать этот прием снова и снова, чтобы увеличить определенную часть дерева разбора. soup.body.b получает тег first <b> под тегом <body>.

Использование имени тега в качестве атрибута даст вам только first тег с таким именем.

Если вам нужно получить все <a> теги или что-нибудь более сложное, чем первый тег с определенным именем, вам понадобится использовать один из методов, описанных в Поиск по дереву , например find_all()

(упор и упущения мои)

Итак, ваш page_soup.div.div найдет впервые в мире div внутри div - и page_soup.div находит впервые div.

<html>

<head>
  <title>The Dormouse's story</title>
</head>

<body>
  <div>first div</div>
  <p>unrelated
  </p>
  <div>second div
    <div>with another div inside</div>
  </div>

  <div>can't get this one by soup.div.div
    <div>with another div inside</div>
  </div>
</body

для этого кода вы можете получить первый код soup.div, а второй - .div.div. Последний, который вы можете получить, выполнив findall().

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