Красивый суп - найти тег внутри тега со строкой?п-й ребенок? - PullRequest
1 голос
/ 21 сентября 2019

У меня возникли проблемы со следующим HTML Scrape

 res =   <div class="gunDetails">
    <h4>Specifications</h4>
    <ul class="features">
        <li><label>Make:</label><span itemprop="brand">Gamo</span></li>
        <li><label>Model:</label><span itemprop="model">Coyote Black Tactical</span></li>
        <li><label>Licence:</label><span>No Licence</span></li>
        <li><label>Orient.:</label><span>Ambidextrous</span></li>
        <li><label>Scope:</label><span>Unknown&nbsp;3-9x32</span></li>
        <li><label>Origin:</label><span>Spanish</span></li>
        <li><label>Cased:</label><span>Other</span></li>
        <li><label>Trigger:</label><span>1</span></li>
        <li><label>Condition:</label><span itemprop="itemCondition">Used</span></li>
    </ul>
  </div>

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

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

soup = BeautifulSoup(res, 'html.parser')
gun_details = soup.select_one('div.gunDetails')
for tag in gun_details or []:
  for tag in gun_details.select("li"):
   for tag in gun_details.select('span'):
      print(tag.text)

Вывод

Gamo
Coyote Black Tactical
No License
Ambidextrous
Unknown 3-9x32
Spanish
Other
1
Used

Есть ли способ, в котором я мог бы создать переменную для каждого текста метки?что-то вроде?

gun_make = gun_details.findAll('label', String="Make:")
print(gun_make).text

Это полный код:

from bs4 import BeautifulSoup
import requests
import csv

all_links=[]
labels = []
spans = []
url="https://www.guntrader.uk/dealers/redcar/spencers-sporting-guns/guns?page={}"

for page in range(1,3):
  res=requests.get(url.format(page)).text
  soup=BeautifulSoup(res,'html.parser')
  for link in soup.select('a[href*="/dealers/redcar/spencers-sporting-guns/guns/shotguns"]'):
  all_links.append("https://www.guntrader.uk" + link['href'])


print(len(all_links))
for a_link in all_links:
  res = requests.get(a_link).text
  soup = BeautifulSoup(res, 'html.parser')
  gun_details = soup.select('div.gunDetails')
  for l in gun_details.select('label'):
   labels.append(l.text.replace(':',''))
  for s in gun_details.select('span'):
   spans.append(s.text)

my_dict = dict(zip(labels, spans))
with open('gundealer.csv','w') as csvfile:
 writer = csv.DictWriter(csvfile, fieldnames=None)
 for key in mydict.keys():
   csvfile.write(f"{key},{my_dict[key]}\n")

Кажется, что этот раздел работает самостоятельно и дает правильный (ish) вывод:

from bs4 import BeautifulSoup
import requests

response = request.get('guntrader.uk/guns/air-rifles/gamo/pre-charged-pneumatic/22/coyote-black-tactical-190920182249936')

soup = BeautifulSoup(response.content, 'html.parser')
gun_details = soup.select_one('div.gunDetails')
gun_make = gun_details.select_one('li:nth-child(1)')
print (gun_make.text)

С выводом:

Make: Gamo

Но я не знаю, что я делаю, чтобы испортить первоначальный ответ из цикла, чтобы не позволить вышеуказанному фрагменту не работать

1 Ответ

1 голос
/ 21 сентября 2019

Давайте попробуем это:

res =  """ <div class="gunDetails">
    <h4>Specifications</h4>
    <ul class="features">
        <li><label>Make:</label><span itemprop="brand">Gamo</span></li>
        <li><label>Model:</label><span itemprop="model">Coyote Black Tactical</span></li>
        <li><label>Licence:</label><span>No Licence</span></li>
        <li><label>Orient.:</label><span>Ambidextrous</span></li>
        <li><label>Scope:</label><span>Unknown&nbsp;3-9x32</span></li>
        <li><label>Origin:</label><span>Spanish</span></li>
        <li><label>Cased:</label><span>Other</span></li>
        <li><label>Trigger:</label><span>1</span></li>
        <li><label>Condition:</label><span itemprop="itemCondition">Used</span></li>
    </ul>
  </div>
""

from bs4 import BeautifulSoup as bs
import csv

labels = []
spans = []
soup = bs(res, 'html.parser')
gun_details = soup.select_one('div.gunDetails')
for l in gun_details.select('label'):
    labels.append(l.text.replace(':',''))
for s in gun_details.select('span'):
    spans.append(s.text)

my_dict = dict(zip(labels, spans))
with open('mycsvfile.csv','w') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=None)
        for key in my_dict.keys():
            csvfile.write(f"{key},{my_dict[key]}\n")

Вывод:

Make    Gamo
Model   Coyote Black Tactical
Licence No Licence
Orient. Ambidextrous
Scope   Unknown 3-9x32
Origin  Spanish
Cased   Other
Trigger 1
Condition   Used
...