Как очистить определенный текст от определенных элементов таблицы - PullRequest
0 голосов
/ 10 июля 2019

Я пытаюсь очистить определенный текст от определенных элементов таблицы на странице продукта Amazon.

URL_1 имеет все элементы - https://www.amazon.com/dp/B008Q5LXIE/ URL_2 имеет только «Ранг продаж» - https://www.amazon.com/dp/B001V9X26S

URL_1: в таблице «Сведения о продукте» есть 9 элементов, и меня интересует тольков разделах «Размеры товара», «Вес отправления», номер модели изделия и все «Ранги продавца»

Я не могу разобрать текст этих предметов, поскольку некоторые находятся в одном блоке кода, а другиене.

Я использую Beautifulsoup, и я запустил text.strip () на столе и получил все, но очень грязно.Я пытался использовать sou.find ('li') и text.strip (), чтобы найти отдельные элементы, но с рангом продавца он возвращает все 3 ранга, перемешанных в одном возврате.Я также попробовал регулярное выражение для очистки текста, но он не будет работать для 4 различных рангов продавца.Я имел успех, используя метод Try, Except, Pass для очистки и имел бы каждый из них в этом формате

A bad example of the code used, I was trying to get sales rank past the </b> 
element in the HTML
#Sales Rank
        sales_rank ='NOT'
        try:
            sr = soup.find('li', attrs={'id':'SalesRank'})
            sales_rank = sr.find('/b').text.strip()
        except:
            pass

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

dimensions = 6x4x4
weight = 4.8 ounces
Item_No = IT-DER0-IQDU
R1_NO = 2,036
R1_CAT = Health & Household
R2_NO = 5
R2_CAT = Joint & Muscle Pain Relief Medications
R3_NO = 3
R3_CAT = Naproxen Sodium
R4_NO = 6
R4_CAT = Migraine Relief

my_dict =   {'dimensions':'dimensions','weight':'weight','Item_No':'Item_No', 'R1_NO':R1_NO,'R1_CAT':'R1_CAT','R2_NO':R2_NO,'R2_CAT':'R2_CAT','R3_NO':R3_NO,'R3_CAT':'R3_CAT','R4_CAT':'R4_CAT'}

URL_2: Единственный элемент, представляющий интерес на странице, - это «Рейтинг продаж».«Размеры продукта», «Вес при транспортировке», номер модели изделия отсутствуют.Тем не менее, я хотел бы получить возвращение, подобное URL_1, но отсутствующие элементы будут иметь значение «NA».Те же результаты, что и в URL_1, только «NA» дается, когда элемент отсутствует.Я успешно выполнил это, установив значение до оператора Try / Except.Пример: Вес Отправления = 'NA' ... затем запустите попытку / исключение: pass, чтобы я получил 'NA', и мой словарь не пуст.

1 Ответ

1 голос
/ 10 июля 2019

Вы можете использовать stripped_strings и: содержит с помощью bs4 4.7.1. Это похоже на множество покерных движений, чтобы получить желаемый выходной формат. Конечно, кто-то с большим опытом работы с Python может уменьшить это и повысить его эффективность. Синтаксис правил объединения взят из @aaronhall.

import requests
from bs4 import BeautifulSoup as bs
import re

links = ['https://www.amazon.com/Professional-Dental-Guard-Remoldable-Customizable/dp/B07L4YHBQ4', 'https://www.amazon.com/dp/B0040ODFK4/?tag=stackoverfl08-20']

for link in links:

    r = requests.get(link, headers = {'User-Agent': 'Mozilla\5.0'})
    soup = bs(r.content, 'lxml')
    fields = ['Product Dimensions', 'Shipping Weight', 'Item model number', 'Amazon Best Sellers Rank']

    temp_dict = {}

    for field in fields:
        element = soup.select_one('li:contains("' + field + '")')
        if element is None:
            temp_dict[field] = 'N/A'
        else:
            if field == 'Amazon Best Sellers Rank':
                item = [re.sub('#|\(','', string).strip() for string in soup.select_one('li:contains("' + field + '")').stripped_strings][1].split(' in ')
                temp_dict[field] = item
            else:
                item = [string for string in element.stripped_strings][1]
                temp_dict[field] = item.replace('(', '').strip()

    ranks = soup.select('.zg_hrsr_rank')
    ladders = soup.select('.zg_hrsr_ladder')

    if ranks:
        cat_nos = [item.text.split('#')[1] for item in ranks]
    else:
         cat_nos = ['N/A']

    if ladders:                      
        cats = [item.text.split('\xa0')[1] for item in soup.select('.zg_hrsr_ladder')]
    else:
        cats = ['N/A']

    rankings = dict(zip(cat_nos, cats))

    map_dict = {
        'Product Dimensions': 'dimensions',
        'Shipping Weight': 'weight', 
        'Item model number': 'Item_No',
        'Amazon Best Sellers Rank': ['R1_NO','R1_CAT']
    }

    final_dict = {}

    for k,v in temp_dict.items():
        if k == 'Amazon Best Sellers Rank' and v!= 'N/A':
            item = dict(zip(map_dict[k],v))
            final_dict = {**final_dict, **item}
        elif k == 'Amazon Best Sellers Rank' and v == 'N/A':
            item = dict(zip(map_dict[k], [v, v]))
            final_dict = {**final_dict, **item}
        else:
            final_dict[map_dict[k]] = v

    for k,v in enumerate(rankings):
        #print(k + 1, v, rankings[v])
        prefix = 'R' + str(k + 2) + '_'
        final_dict[prefix + 'NO'] = v  
        final_dict[prefix + 'CAT'] = rankings[v]

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