#python #json #selenium #web-scraping #beautifulsoup
Вопрос:
Я почти доволен этим сценарием, который я составлял сегодня. Сегодня он пришел с некоторой помощью (спасибо всем, кто помогал до сих пор) и некоторым подозрительным программированием с моей стороны, но в какой-то степени он функционален.
Я хочу сбросить данные в JSON. Кажется, что все данные правильно сброшены, кроме цены (из которой была взята <span></span>
). Я считаю, что проблема заключается в отступе, но я не уверен на 100%.
Не мог бы кто-нибудь взглянуть на этот фрагмент и исправить то, что я не вижу. Думаю, я ослепну из-за того, что не могу увидеть правильные изменения с тем количеством вариаций, которые я пробовал.
from bs4 import BeautifulSoup
import requests
import shutil
import csv
import pandas
from pandas import DataFrame
import re
import os
import urllib.request as urllib2
import locale
import json
from selenium import webdriver
import lxml.html
import time
from selenium.webdriver.support.ui import Select
os.environ["PYTHONIOENCODING"] = "utf-8"
#selenium requests
browser = webdriver.Chrome(executable_path='C:/Users/admin/chromedriver.exe')
browser.get("https://www.mcavoyguns.co.uk/contents/en-uk/d130_Beretta_Over___Under_Competeition_shotguns.html")
time.sleep(2)
#beautiful soup requests
#URL = 'https://www.mcavoyguns.co.uk/contents/en-uk/d130_Beretta_Over___Under_Competeition_shotguns.html'
#page = requests.get(URL)
#soup = BeautifulSoup(page.content, 'html.parser')
soup = BeautifulSoup(browser.page_source, features="lxml")
#products = soup.find_all("div", "GC62 Product")
products = soup.find_all("div", "GC62 Product")
for product in products:
#barrel lengths
barrels = product.find('select', attrs={'name': re.compile('length')})
if barrels:
barrels_list = [x['origvalue'][:2] for x in barrels.find_all('option')[1:]]
for y in range(0, len(barrels_list)):
#title
title = product.find("h3")
titleText = title.text if title else ''
#manufacturer name
manufacturer = product.find("div", "GC5 ProductManufacturer")
manuText = manufacturer.text if manufacturer else ''
#image location
img = product.find("div", "ProductImage")
imglinks = img.find("a") if img else ''
imglinkhref = imglinks.get('href') if imglinks else ''
imgurl = 'https://www.mcavoyguns.co.uk/contents' imglinkhref
#description
description = product.find("div", "GC12 ProductDescription")
descText = description.text if description else ''
#descStr = str(descText)
#more description
more = product.find("div", "GC12 ProductDetailedDescription")
moreText = more.text if more else ''
#price
spans = browser.find_elements_by_css_selector("div.GC20.ProductPrice span")
for i in range(0,len(spans),2):
span = spans[i].text
i =1
#print(span)
#print(barrels_list[y])
#print(titleText)
#print(manuText)
#print(descText)
#print(moreText)
#print(imgurl.replace('..', ''))
#print("n")
x = {
"price": span,
"barrel length": barrels_list[y],
"title": titleText,
"manufacturer": manuText,
"description": descText,
"desc cont": moreText,
"image Location": imgurl.replace('..', '')
}
dump = json.dumps(x)
print(dump)
y =1
Ответ №1:
Мне удалось заставить его работать, немного изменив ваш код. Ваш последний for
цикл на самом деле не очень полезен, так как вы уже нашли тег продукта. Таким образом, вы можете поступить следующим образом :
from bs4 import BeautifulSoup
import requests
import shutil
import csv
import pandas
from pandas import DataFrame
import re
import os
import urllib.request as urllib2
import locale
import json
from selenium import webdriver
import lxml.html
import time
from selenium.webdriver.support.ui import Select
os.environ["PYTHONIOENCODING"] = "utf-8"
#selenium requests
browser = webdriver.Chrome(executable_path='C:/Users/admin/chromedriver.exe')
browser.get("https://www.mcavoyguns.co.uk/contents/en-uk/d130_Beretta_Over___Under_Competeition_shotguns.html")
time.sleep(2)
#beautiful soup requests
#URL = 'https://www.mcavoyguns.co.uk/contents/en-uk/d130_Beretta_Over___Under_Competeition_shotguns.html'
#page = requests.get(URL)
#soup = BeautifulSoup(page.content, 'html.parser')
soup = BeautifulSoup(browser.page_source, features="lxml")
#products = soup.find_all("div", "GC62 Product")
products = soup.find_all("div", "GC62 Product")
for product in products:
#barrel lengths
barrels = product.find('select', attrs={'name': re.compile('length')})
if barrels:
barrels_list = [x['origvalue'][:2] for x in barrels.find_all('option')[1:]]
#title
title = product.find("h3")
titleText = title.text if title else ''
#manufacturer name
manufacturer = product.find("div", "GC5 ProductManufacturer")
manuText = manufacturer.text if manufacturer else ''
#image location
img = product.find("div", "ProductImage")
imglinks = img.find("a") if img else ''
imglinkhref = imglinks.get('href') if imglinks else ''
imgurl = 'https://www.mcavoyguns.co.uk/contents' imglinkhref
#description
description = product.find("div", "GC12 ProductDescription")
descText = description.text if description else ''
#more description
more = product.find("div", "GC12 ProductDetailedDescription")
moreText = more.text if more else ''
#price
price = product.findChild(name="span")
print("price : ", price)
price_raw = price.text
print("price_raw : ", price_raw)
price_replaced = price_raw.replace(',', '').replace('£', '')
print("price_replaced : ", price_replaced)
price_float = float(price_replaced)
for barrel in barrels_list:
x = {
"price": price_float,
"barrel length": barrel,
"title": titleText,
"manufacturer": manuText,
"description": descText,
"desc cont": moreText,
"image Location": imgurl.replace('..', '')
}
dump = json.dumps(x)
print(dump)
Не стесняйтесь, если это все еще не работает!
Комментарии:
1. Ммм, это работает на моей стороне! Я попытался упростить код, можете ли вы попробовать скопировать/вставить, чтобы посмотреть, работает ли он? Кстати, при использовании
for
инструкции не нужно добавлятьx = 1
в конце,for
инструкция увеличивает ее сама по себе!2. Хорошо, давайте отладим это, не могли бы вы дать мне то, что напечатано на вашем экране для всех
price_...
(см. Мой код с новымиprint()
строками 65, 67, 69 и 71)3. Интересно, давайте попробуем что-нибудь немного другое, попробуем код nex
![]()
4. Ааааа, я вижу, что происходит, на моем экране
£
знак стоит за суммой. Я хотел перевести сумму в плавающую, но, может быть, вам это не нужно?5. См.Отредактированный код для приведения в плавающее состояние. Если это не сработает, можете ли вы просто дать мне значение печати
price.text
, и я заставлю его работать?