Как схватить первого ребенка в своем роде - PullRequest
0 голосов
/ 24 октября 2019

Я пытаюсь перехватить данные с двух узлов с одинаковыми именами. Я использую метод find, но он всегда извлекает вложенное значение, а не первый дочерний узел. Я пробовал несколько разных методов, но у меня ничего не получилось. Любая помощь приветствуется, как всегда.

API Response:


<affiliate_export_response>
  <success>true</success>
  <row_count>1</row_count>
  <affiliates>
      <blacklists>
        <blacklist>
          <advertiser>
            <advertiser_id xmlns="API:id_name_store">2</advertiser_id>
            <advertiser_name xmlns="API:id_name_store">wayne's Ad</advertiser_name>
          </advertiser>
          <affiliate>
            <affiliate_id xmlns="API:id_name_store">3</affiliate_id>
            <affiliate_name xmlns="API:id_name_store">Mark Affiliate</affiliate_name>
          </affiliate>
          <blacklist_reason>
            <blacklist_reason_id xmlns="API:id_name_store">1</blacklist_reason_id>
            <blacklist_reason_name xmlns="API:id_name_store">404</blacklist_reason_name>
          </blacklist_reason>
          <blacklist_type>
            <blacklist_type_id xmlns="API:id_name_store">3</blacklist_type_id>
            <blacklist_type_name xmlns="API:id_name_store">404</blacklist_type_name>
          </blacklist_type>
          <date_created>2018-04-26T00:00:00</date_created>
        </blacklist>
      </blacklists>
      <date_created>2018-01-29T11:40:58.34</date_created>
      <notes />
    </affiliate>
  </affiliates>
</affiliate_export_response>

Code:

import requests
from bs4 import BeautifulSoup

url = 'API URL'
params = {
          'param1':'dfasdf',
          'param2':3
          }
r = requests.get(url, params=params)
soup = BeautifulSoup(r.text, 'lxml')
for affiliate in soup.select('affiliate'):
     date_created = affiliate.find('date_created').string
     print(date_created)

Цель состоит в том, чтобы захватить 2018-01-29T11: 40: 58.34, но я собираю вложенный узел date_created внутри черных списков и получаю 2018-04-26T00: 00:00 вместо

Ответы [ 2 ]

0 голосов
/ 24 октября 2019

В этом конкретном примере с bs4 4.7.1+ вы можете использовать nth-child (even) в вашем цикле над аффилированными узлами.

import requests
from bs4 import BeautifulSoup as bs

html = '''
<affiliate_export_response>
    <success>true</success>
    <row_count>1</row_count>
    <affiliates>
        <affiliate>
        <blacklists>
          <blacklist>
            <advertiser>
              <advertiser_id xmlns="API:id_name_store">2</advertiser_id>
              <advertiser_name xmlns="API:id_name_store">wayne's Ad</advertiser_name>
            </advertiser>
            <affiliate>
              <affiliate_id xmlns="API:id_name_store">3</affiliate_id>
              <affiliate_name xmlns="API:id_name_store">Mark Affiliate</affiliate_name>
            </affiliate>
            <blacklist_reason>
              <blacklist_reason_id xmlns="API:id_name_store">1</blacklist_reason_id>
              <blacklist_reason_name xmlns="API:id_name_store">404</blacklist_reason_name>
            </blacklist_reason>
            <blacklist_type>
              <blacklist_type_id xmlns="API:id_name_store">3</blacklist_type_id>
              <blacklist_type_name xmlns="API:id_name_store">404</blacklist_type_name>
            </blacklist_type>
            <date_created>2018-04-26T00:00:00</date_created>
          </blacklist>
        </blacklists>
        <date_created>2018-01-29T11:40:58.34</date_created>
        <notes />
      </affiliate>
    </affiliates>
  </affiliate_export_response>
'''
soup = bs(html, 'lxml')
for item in soup.select('affiliate'):
    date = item.select_one('date_created:nth-child(even)')
    if date is None:
        print('N/A')
    else:
        print(date.text)
0 голосов
/ 24 октября 2019

Прежде всего, вам не хватает открытия тега для affiliate, из-за чего ваш парсер не работает

<affiliate_export_response>
    <success>true</success>
    <row_count>1</row_count>
    <affiliates>
        <affiliate> ======================= This was missing ================
        <blacklists>
          <blacklist>
            <advertiser>
              <advertiser_id xmlns="API:id_name_store">2</advertiser_id>
              <advertiser_name xmlns="API:id_name_store">wayne's Ad</advertiser_name>
            </advertiser>
            <affiliate>
              <affiliate_id xmlns="API:id_name_store">3</affiliate_id>
              <affiliate_name xmlns="API:id_name_store">Mark Affiliate</affiliate_name>
            </affiliate>
            <blacklist_reason>
              <blacklist_reason_id xmlns="API:id_name_store">1</blacklist_reason_id>
              <blacklist_reason_name xmlns="API:id_name_store">404</blacklist_reason_name>
            </blacklist_reason>
            <blacklist_type>
              <blacklist_type_id xmlns="API:id_name_store">3</blacklist_type_id>
              <blacklist_type_name xmlns="API:id_name_store">404</blacklist_type_name>
            </blacklist_type>
            <date_created>2018-04-26T00:00:00</date_created>
          </blacklist>
        </blacklists>
        <date_created>2018-01-29T11:40:58.34</date_created>
        <notes />
      </affiliate>
    </affiliates>
  </affiliate_export_response>

Используйте это, чтобы получить дату создания только партнера

from bs4 import BeautifulSoup
soup = BeautifulSoup(text, 'html.parser')
for affiliate in soup.select('affiliate > date_created'):
     parent = affiliate.parent
     print(affiliate.text)

Демо: Здесь

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