Поэтому у меня есть эти веб-данные, которые я соскреб с веб-сайта продукта. Я очистил его с помощью BeautifulSoup и скопировал несколько страниц с веб-сайта продукта. Я получаю два списка из скребка, один из спецификаций, а другой — данные для спецификации. Вот пример:

Blade length : 2.97/1.97" 
Blade Thickness : 0.090/2.54" 
Open Length :   7.05/6.05" 
Closed Length:  4.08" | 9.78cm
Handle Thickness:   0.40" | 10.16mm
Weight: 2.28oz | 64.64g

Я хочу, чтобы левая сторона была ключом для словаря, а правая сторона - значением. Конечная цель состоит в том, чтобы поместить его в CSV, где я могу иметь левую часть, чтобы быть заголовками столбцов для данных в правой части. Поскольку я очищаю несколько страниц, левая сторона повторяется, а правая часть имеет несколько значений.

Таким образом, желаемый результат должен быть примерно таким:

 Blade Length. | | Blade Thickness|| Open Length |--etc etc
|------------- | |----------------||-------------| 
| 2.97/1.97"   | |  4.34/12.54    ||  1.23/5.65  |  
| 4.24/2.23"   | |  2.34/5.63     ||  5.43/2.90  |  
| 3.54/2.65    | |  2.57/6.54     ||  6.90/4.20  |  
| 7.65/5/43    | |  4.65/3.56     ||  3.32/4.54  |  

Так что если есть лучший способ сделать это, чем словари, пожалуйста, дайте мне знать!

HTML выглядит примерно так:

<table class="specifications-table">
     <tbody>
               <tr>
                    <th class="col label">Blade Length:</th>
                    <td class="col value">2.97/1.97"</td>
               </tr>
               <tr>
                    <th class="col label">Blade Thickness:</th>
                    <td class="col value">0.090"</td>
               </tr>
               <tr>
                    <th class="col label">Open Length: </th>
                    <td class="col value">7.05/6.05"</td>
               </tr>
               <tr>
                    <th class="col label">Closed Length: </th>
                    <td class="col value">4.08"</td>
               </tr>
               <tr>
                    <th class="col label">Handle Thickness:</th>
                    <td class="col value">0.40" </td>
               </tr>
               <tr>
                    <th class="col label">Weight:</th>
                    <td class="col value">2.28oz</td>
               </tr>
      </tbody>
</table>

Вот моя попытка получить эти данные:

Specs = []
Specs_Datas = defaultdict(list)
Specs2 = []
for links in product_links:
    HTML2 = requests.get(links, HEADER)
    Booti2 = soup(HTML2.content,"html.parser") 
    table_feature = Booti2.select_one('#product-attribute-specs-table')
    #find all rows
    try:
        for S in Booti2.find_all('th', attrs ={'class': 'col label'}):
            Specs.append(S.text.replace('\n', '').strip())
            unique_specs = np.unique(Specs).tolist()
            while unique_specs in Specs:
                for SD in Booti2.find_all('td', attrs ={'class': 'col value'}):
                    Specs2.append(SD.text.replace('\n', '').strip())
                    Specs_Datas[unique_specs] = []
                    Specs_Datas[unique_specs].update(SD.text.replace('\n', '').strip())
            #Specs.append(S.text.replace('\n', '').strip())
            
    except:
        continue

Любая помощь будет оценена!! Большое спасибо!!!

-1
Hamza Ahmed 26 Янв 2022 в 17:58
4
Как будет выглядеть желаемый результат?
 – 
baduker
26 Янв 2022 в 18:00
Я хочу, чтобы это была таблица с толщиной лезвия, длиной лезвия и т. Д., Которая должна быть заголовками столбцов, а все ее значения - строками.
 – 
Hamza Ahmed
26 Янв 2022 в 18:14
Это в вопросе. Таблица, показанная в вопросе, является желаемым результатом!
 – 
Hamza Ahmed
26 Янв 2022 в 18:41

2 ответа

Вы можете позволить pandas анализировать тег <table> и транспонировать его. Затем вы добавляете транспонированные таблицы в result_df.

Это сложно показать с ограниченным кодом, который у вас есть здесь, но это основная идея:

import pandas as pd


html = '''<table class="specifications-table">
     <tbody>
               <tr>
                    <th class="col label">Blade Length:</th>
                    <td class="col value">2.97/1.97"</td>
               </tr>
               <tr>
                    <th class="col label">Blade Thickness:</th>
                    <td class="col value">0.090"</td>
               </tr>
               <tr>
                    <th class="col label">Open Length: </th>
                    <td class="col value">7.05/6.05"</td>
               </tr>
               <tr>
                    <th class="col label">Closed Length: </th>
                    <td class="col value">4.08"</td>
               </tr>
               <tr>
                    <th class="col label">Handle Thickness:</th>
                    <td class="col value">0.40" </td>
               </tr>
               <tr>
                    <th class="col label">Weight:</th>
                    <td class="col value">2.28oz</td>
               </tr>
      </tbody>
</table>'''

df = pd.read_html(html)[0].set_index(0).T

Вывод:

print(df)
0 Blade Length: Blade Thickness:  ... Handle Thickness: Weight:
1    2.97/1.97"           0.090"  ...             0.40"  2.28oz
1
chitown88 26 Янв 2022 в 18:52
Мне нравится это как более целостное переформулирование задачи.
 – 
JonSG
26 Янв 2022 в 19:42

Предполагая, что у вас на самом деле есть два списка:

specs = [
    "Blade length",
    "Blade Thickness",
    "Open Length",
    "Closed Length",
    "Handle Thickness",
    "Weight"
]

А также

spec_data = [
    "2.97/1.97\"",
    "0.090/2.54\"",
    "7.05/6.05\"",
    "4.08\" | 9.78cm",
    "0.40\" | 10.16mm",
    "2.28oz | 64.64g"
]

Самый простой путь может состоять в том, чтобы zip() их вместе:

specs_reshaped = [
    {key: value for key, value in zip(specs, spec_data)}
]

Затем используйте DictWriter()

with open("output.csv", "w", newline="", encoding="utf-8") as file_out:
    writer = csv.DictWriter(file_out, fieldnames=specs)
    writer.writeheader()
    writer.writerows(specs_reshaped)

Это создает файл вида:

Blade length,Blade Thickness,Open Length,Closed Length,Handle Thickness,Weight
"2.97/1.97""","0.090/2.54""","7.05/6.05""","4.08"" | 9.78cm","0.40"" | 10.16mm",2.28oz | 64.64g
0
JonSG 26 Янв 2022 в 18:52