Не удалось извлечь все URL из json Script с помощью beautifulsoup3 - PullRequest
0 голосов
/ 08 января 2019
   import requests
from bs4 import BeautifulSoup
import json
import re

url = "https://www.daraz.pk/catalog/?q=dell&_keyori=ss&from=input&spm=a2a0e.searchlist.search.go.57446b5079XMO8"
page = requests.get(url)

print(page.status_code)
print(page.text)
soup = BeautifulSoup(page.text, 'html.parser')
print(soup.prettify())



alpha = soup.find_all('script',{'type':'application/ld+json'})

jsonObj = json.loads(alpha[1].text)

Ниже приведен код для поиска всей необходимой информации о продукте из объекта json

for item in jsonObj['itemListElement']:
    name = item['name']
    price = item['offers']['price']
    currency = item['offers']['priceCurrency']
    availability = item['offers']['availability'].split('/')[-1]
    availability = [s for s in re.split("([A-Z][^A-Z]*)", availability) if s]
    availability = ' '.join(availability)

Вот код для извлечения URL для скрипта json

    url = item['url']

print('Availability: %s  Price: %0.2f %s   Name: %s' %(availability,float(price), currency,name, url))

Ниже приведен код для извлечения данных inro csv:

outfile = open('products.csv','w', newline='')
writer = csv.writer(outfile)
writer.writerow(["name", "type", "price", "priceCurrency", "availability" ])

alpha = soup.find_all('script',{'type':'application/ld+json'})

jsonObj = json.loads(alpha[1].text)

for item in jsonObj['itemListElement']:
    name = item['name']
    type = item['@type']
    url = item['url']
    price = item['offers']['price']
    currency = item['offers']['priceCurrency']
    availability = item['offers']['availability'].split('/')[-1]

Файл создает заголовок, но нет данных в CSV для URL

writer.writerow([name, type, price, currency, availability, URL ])
outfile.close()

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Единственное, что я могу найти неправильно, это то, что у вас есть опечатка в последней строке - верхний регистр URL вместо строчного url. Его изменение сделало скрипт отлично работающим.

0 голосов
/ 08 января 2019

во-первых, вы не включаете заголовок там. ничего страшного, только в первой строке будет пустое место для вашего заголовка в столбце url. Итак, чтобы включить это:

writer.writerow(["name", "type", "price", "priceCurrency", "availability", "url" ]) 

Во-вторых, вы сохраняете строку как url, но затем ссылаетесь на URL в своей записи. URL не имеет значения. Фактически, это должно было дать ошибку URL is not defined или что-то подобное.

И поскольку вы уже используете url в своем коде с url = "https://www.daraz.pk/catalog/?q=dell&_keyori=ss&from=input&spm=a2a0e.searchlist.search.go.57446b5079XMO8", я бы, вероятно, также изменил имя переменной на что-то вроде url_text.

Возможно, я бы также использовал переменную type_text или что-то отличное от type, так как type является встроенной функцией в python.

Но вам нужно изменить на:

writer.writerow([name, type, price, currency, availability, url ])
outfile.close()

Полный код:

import requests
from bs4 import BeautifulSoup
import json
import csv

url = "https://www.daraz.pk/catalog/?q=dell&_keyori=ss&from=input&spm=a2a0e.searchlist.search.go.57446b5079XMO8"
page = requests.get(url)

print(page.status_code)
print(page.text)
soup = BeautifulSoup(page.text, 'html.parser')
print(soup.prettify())



alpha = soup.find_all('script',{'type':'application/ld+json'})

jsonObj = json.loads(alpha[1].text)

outfile = open('c:\products.csv','w', newline='')
writer = csv.writer(outfile)
writer.writerow(["name", "type", "price", "priceCurrency", "availability" , "url"])

for item in jsonObj['itemListElement']:
    name = item['name']
    type_text = item['@type']
    url_text = item['url']
    price = item['offers']['price']
    currency = item['offers']['priceCurrency']
    availability = item['offers']['availability'].split('/')[-1]

    writer.writerow([name, type_text, price, currency, availability, url_text ])

outfile.close()
...