У меня проблемы с выводом этого скрипта. Когда ответ возвращается, ответ «подробности» содержит фразу «\n». Как я могу сохранить ответ в формате csv без «\n»? Спасибо за любые предложения.
from requests_html import HTMLSession
def getPrice(url):
s = HTMLSession()
r = s.get(url)
r.html.render(sleep=1)
product = {
'title': r.html.xpath('//*[@id = "productTitle"]', first=True).text,
'price': r.html.xpath('//*[@id = "priceblock_ourprice"]', first=True).text,
'details': r.html.xpath('//*[@id = "prodDetails"]/div/div[1]/div', first=True).text
}
print(product)
return product
getPrice('https://www.amazon.com/dp/B07HXN1V51')
Выслеживать
{'title': 'Charades Party Game – Speed Charades Board Game – Fast-Paced Party Game - Perfect for Groups and Family Game Nights', 'price': '$24.99', 'details': 'Product Dimensions\n10.25 x 8.5 x 2.6 inches\nItem Weight\n1.75 pounds\nASIN\nB07HXN1V51\nItem model number\n8291\nManufacturer recommended age\n13 years and up\nBest Sellers Rank\n#2,811 in Toys & Games (See Top 100 in Toys & Games)\n#191 in Board Games (Toys & Games)\n\nCustomer Reviews\n/* * Fix for UDP-1061. Average customer reviews has a small extra line on hover * https://omni-grok.amazon.com/xref/src/appgroup/websiteTemplates/retail/SoftlinesDetailPageAssets/udp-intl-lock/src/legacy.css?indexName=WebsiteTemplates#40 */ .noUnderline a:hover { text-decoration: none; }\n4.7 out of 5 stars 682 ratings P.when(\'A\', \'ready\').execute(function(A) { A.declarative(\'acrLink-click-metrics\', \'click\', { "allowLinkDefault" : true }, function(event){ if (window.ue) { ue.count("acrLinkClickCount", (ue.count("acrLinkClickCount") || 0) + 1); } }); }); P.when(\'A\', \'cf\').execute(function(A) { A.declarative(\'acrStarsLink-click-metrics\', \'click\', { "allowLinkDefault" : true }, function(event){ if (window.ue) { ue.count("acrStarsLinkWithPopoverClickCount", (ue.count("acrStarsLinkWithPopoverClickCount") || 0) + 1); } }); });\n\n4.7 out of 5 stars\nIs Discontinued By Manufacturer\nNo\nMfg Recommended age\n13 year and up\nManufacturer\nThe GAME CHEF'}
@JackFleeting Привет, я хочу, чтобы ответ был в формате электронной таблицы со столбцами, такими как заголовок, цена, подробности и данные, которые должны быть в строках. Имеет ли это смысл?
ты пробовал так ' '.join(r.html.xpath('//*[@id = "prodDetails"]/div/div[1]/div', first=True).text.split())
Предполагая, что значения вашего словаря - это просто строки, я бы использовал замену.
Например
res = {}
for key in list(product):
res[key] = product[key].replace('\n',' ')
print(res)
return res
Дополнительная информация о методе замены:
Возможно, вы сможете выполнить преобразование на месте, я не могу вспомнить, разрешено ли это для словарей.
Редактировать
Для сохранения в формате csv:
import pandas as pd
df = pd.DataFrame(products)
df.to_csv('my_products_csv.csv')
Здравствуйте, предоставленный вами сценарий замены не заменяет индикатор новой строки. Можете ли вы дать больше объяснений, пожалуйста?
Я не уверен, какой тип данных выводится для вашей операции r.html.xpath().text
, поэтому вам может понадобиться обернуть все это преобразованием строки, например str(r.html.xpath().text)
. В противном случае метод замены является родным для строковых объектов в python.
Попробуйте это, чтобы избавиться от тарабарщины, создаваемой тегами script и style. Кроме того, проблема с новой строкой была решена. Я использовал библиотеку bs4
в сочетании с requests_html
, чтобы удалить ненужные теги.
from requests_html import HTMLSession
from bs4 import BeautifulSoup
def getPrice(url):
s = HTMLSession()
r = s.get(url)
r.html.render(sleep=1)
soup = BeautifulSoup(r.html.raw_html,"html.parser")
[script.extract() for script in soup.select("script,style")]
product = {
'title': soup.select_one('span#productTitle').get_text(strip=True),
'price': soup.select_one('#priceblock_ourprice').get_text(strip=True),
'details': ' '.join(soup.select_one('table[class$ = "prodDetTable"]').text.split())
}
return product
print(getPrice('https://www.amazon.com/dp/B07HXN1V51'))
Обновлено:
Я не уверен, что это то, что вы имели в виду:
try:
title = soup.select_one('span#productTitle').get_text(strip=True)
except AttributeError: title = ''
try:
price = soup.select_one('#priceblock_ourprice').get_text(strip=True)
except AttributeError: price = ''
try:
details = ' '.join(soup.select_one('table[class$ = "prodDetTable"]').text.split())
except AttributeError: details = ''
product = {
'title': title,
'price': price,
'details': details
}
Что делать, если раздел с названием, ценой или деталями недоступен? Как я могу реализовать оператор else?
Ваш вопрос не ясен: как именно вы хотите, чтобы этот ответ выглядел как строка csv?