Python & Beautifulsoup 4 - оптимизация скребкового кода - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь очистить несколько веб-сайтов для определенных продуктов, и я уверен, что есть способ оптимизировать мой код.На данный момент код выполняет свою работу, но на самом деле это не Pythonic способ сделать это (я новичок в Python, поэтому, пожалуйста, извините за отсутствие у меня знаний).

Цель этой программы - получить цены на товары по указанным URL-адресам и записать их в файл .csv.Каждый сайт имеет разную структуру, но я всегда использую одни и те же 3 сайта.Это пример моего текущего кода:

import requests
import csv
import io
import os
from datetime import datetime
from bs4 import BeautifulSoup

timeanddate=datetime.now().strftime("%Y%m%d-%H%M%S")

folder_path = 
'my_folder_path'
file_name = 'product_prices_'+timeanddate+'.csv'
full_name = os.path.join(folder_path, file_name)

with io.open(full_name, 'w', newline='', encoding="utf-8") as file:
 writer = csv.writer(file)
writer.writerow(["ProductTitle", "Website1", "Website2", "Website3"])

#---Product 1---
#Website1 price
website1product1 = requests.get('website1product1URL')
website1product1Data = BeautifulSoup(website1product1.text, 'html.parser')
website1product1Price = website1product1Data.find('div', attrs={'class': 'price-final'}).text.strip()
print(website1product1Price)

#Website2 price
website2product1 = requests.get('website2product1URL')
website2product1Data = BeautifulSoup(website2product1.text, 'html.parser')
website2product1Price = website2product1Data.find('div', attrs={'class': 'price_card'}).text.strip()
print(website2product1Price)

#Website3 price
website3product1 = requests.get('website3product1URL')
website3product1Data = BeautifulSoup(website3product1.text, 'html.parser')
website3product1Price = website3product1Data.find('strong', attrs={'itemprop': 'price'}).text.strip()
print(website3product1Price)

writer.writerow(["ProductTitle", website1product1Price, website2product1Price, website3product1Price])

file.close()

Он сохраняет названия продуктов и цены в формате .csv в этом формате, и я хотел бы сохранить этот формат:

#Header
ProductTitle Website1 Website2 Website3
#Scraped data
Product1     $23      $24      $52

Это возможно для нескольких продуктов, но я хотел бы иметь сотни и копировать одни и те же строки кода, а изменение имен переменных сбивает с толку, утомительно и неизбежно приводит к человеческим ошибкам.

Могу ли я создать функцию, которая принимает 3 URL-адреса в качестве аргументов и выводит website1product1Price, website2product1Price и website2product1Price, и вызывать эту функцию один раз для каждого продукта?Можно ли затем обернуть его в цикл, чтобы просмотреть список URL-адресов и сохранить первоначальное форматирование?

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Вы можете создать функцию и передать все в качестве параметра, например url, tag_name, attribute_name и attribute_value. См., Если это поможет.

def price_text(url_text,ele_tag,ele_attr,attrval):
 website1product1 = requests.get(url_text)
 website1product1Data = BeautifulSoup(website1product1.text, 'html.parser')
 website1product1Price=website1product1Data.find("'" + ele_tag + "'", attrs="{'" + ele_attr + "': '" + attrval + "'}").text.strip()
 print(website1product1Price)

website1product1Price=price_text("url","div","class","price-final")
website1product2Price=price_text("url","div","class","price_card")
website1product3Price=price_text("url","strong","itemprop","price")
0 голосов
/ 04 марта 2019

Может ли это быть решением для вас?Допустим, у вас есть массив dict для вашего продукта:

products = [
    {
      'name': 'product1',
      'url1': 'https://url1',
      'url2': 'https://url2',
      'url3': 'https://url3'
    }
]

Ваш код может выглядеть примерно так:

import requests
import csv
import io
import os
from datetime import datetime
from bs4 import BeautifulSoup

def get_product_prices(product):

    #---Product 1---
    #Website1 price
    website1product1 = requests.get(product['url1'])
    website1product1Data = BeautifulSoup(website1product1.text, 'html.parser')
    website1product1Price = website1product1Data.find('div', attrs={'class': 'price-final'}).text.strip()

    #Website2 price
    website2product1 = requests.get(product['url2'])
    website2product1Data = BeautifulSoup(website2product1.text, 'html.parser')
    website2product1Price = website2product1Data.find('div', attrs={'class': 'price_card'}).text.strip()

    #Website3 price
    website3product1 = requests.get(product['url3'])
    website3product1Data = BeautifulSoup(website3product1.text, 'html.parser')
    website3product1Price = website3product1Data.find('strong', attrs={'itemprop': 'price'}).text.strip()

    return website1product1Price, website2product1Price, website3product1Price

timeanddate=datetime.now().strftime("%Y%m%d-%H%M%S")

folder_path = 
'my_folder_path'
file_name = 'product_prices_'+timeanddate+'.csv'
full_name = os.path.join(folder_path, file_name)

with io.open(full_name, 'w', newline='', encoding="utf-8") as file:
    writer = csv.writer(file)
    writer.writerow(["ProductTitle", "Website1", "Website2", "Website3"])

    for product in products:
        price1, price2, price3 = get_product_prices(product)
        write.writerow(product['name'], price1, price2, price3)

file.close()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...