Web Scraping - объект ResultSet не имеет атрибута 'findAll' - PullRequest
0 голосов
/ 23 февраля 2020

Возникла проблема с bs4 при чтении второго значения в массиве в течение l oop. Ниже я буду пробовать код - извиняюсь, он может быть довольно длинным (~ 60 строк).

Однако - Когда я использую строку № 19, я не получаю ошибок. Когда я обмениваю его на весь массив (строка № 18), он выдает ошибку при попытке собрать второе значение. Обратите внимание, что второе значение в массиве совпадает со значением строки № 19.

import requests
import bs4
from urllib.request import urlopen as uReq
from bs4 import BeautifulSoup as soup


SmartLiving_IDS = "https://www.hayneedle.com/search/index.cfm?categoryID=&page=1&searchQuery=Smart%20Living&selectedFacets=Brand%7CSmart%20Living&sortBy="
IEL_IDS = "https://www.hayneedle.com/search/index.cfm?categoryID=&page=1&searchQuery=IEL&selectedFacets=Brand%7CIts%20Exciting%20Lighting&sortBy="
TD_IDS = "https://www.hayneedle.com/search/index.cfm?categoryID=&page=1&searchQuery=two%20dogs&selectedFacets=Brand%7CTwo%20Dogs%20Designs&sortBy="

Headers = "Description, URL, Price \n"

text_file = open("HayneedlePrices.csv", "w")
text_file.write(Headers)
text_file.close()


URL_Array = [SmartLiving_IDS, IEL_IDS, TD_IDS]
#URL_Array = [IEL_IDS]
for URL in URL_Array:
  print("\n" + "Loading New URL:" "\n" + URL + "\n" + "\n")

  uClient = uReq(URL)
  page_html = uClient.read()
  uClient.close() 
  soup = soup(page_html, "html.parser")

  Containers = soup.findAll("div", {"product-card__container___1U2Sb"})
  for Container in Containers:


    Title             = Container.div.img["alt"]    
    Product_URL       = Container.a["href"]

    Price_Container   = Container.findAll("div", {"class":"product-card__productInfo___30YSc body no-underline txt-black"})[0].findAll("span", {"style":"font-size:20px"})

    Price_Dollars     = Price_Container[0].get_text()
    Price_Cents       = Price_Container[1].get_text()


    print("\n" + "#####################################################################################################################################################################################################" + "\n")
    # print("   Container: " + "\n" + str(Container))
    # print("\n" + "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------" + "\n")
    print(" Description: " + str(Title))
    print(" Product URL: " + str(Product_URL))
    print("       Price: " + str(Price_Dollars) + str(Price_Cents))
    print("\n" + "#####################################################################################################################################################################################################" + "\n")

    text_file = open("HayneedlePrices.csv", "a")
    text_file.write(str(Title) +  ", " + str(Product_URL) + ", " + str(Price_Dollars) + str(Price_Cents) + "\n")
    text_file.close()

  print("Information gathered and Saved from URL Successfully.")
  print("Looking for Next URL..")
print("No Additional URLs to Gather. Process Completed.")

1 Ответ

0 голосов
/ 24 февраля 2020

Проблема в том, что вы import BeautifulSoup as soup также определяете переменную soup = soup(page_html, "html.parser") с тем же именем!

Я немного реорганизовал ваш код, дайте мне знать, работает ли он должным образом!

import csv

import requests
from bs4 import BeautifulSoup

smart_living_IDS = "https://www.hayneedle.com/search/index.cfm?categoryID=&page=1&searchQuery=Smart%20Living&selectedFacets=Brand%7CSmart%20Living&sortBy="
IEL_IDS = "https://www.hayneedle.com/search/index.cfm?categoryID=&page=1&searchQuery=IEL&selectedFacets=Brand%7CIts%20Exciting%20Lighting&sortBy="
TD_IDS = "https://www.hayneedle.com/search/index.cfm?categoryID=&page=1&searchQuery=two%20dogs&selectedFacets=Brand%7CTwo%20Dogs%20Designs&sortBy="

site_URLs = [smart_living_IDS, IEL_IDS, TD_IDS]

sess = requests.Session()

prod_data = []

for curr_URL in site_URLs:
    req = sess.get(url=curr_URL)
    soup = BeautifulSoup(req.content, "lxml")

    containers = soup.find_all("div", {"product-card__container___1U2Sb"})
    for curr_container in containers:
        prod_title = curr_container.div.img["alt"]
        prod_URL = curr_container.a["href"]

        price_container = curr_container.find(
            "div",
            {"class": "product-card__productInfo___30YSc body no-underline txt-black"},
        )

        dollars_elem = price_container.find("span", {"class": "main-price-dollars"})
        cents_elem = dollars_elem.find_next("span")

        prod_price = dollars_elem.get_text() + cents_elem.get_text()
        prod_price = float(prod_price[1:])

        prod_data.append((prod_title, prod_URL, prod_price))

CSV_headers = ("title", "URL", "price")

with open("../out/hayneedle_prices.csv", "w", newline="") as file_out:
    writer = csv.writer(file_out)
    writer.writerow(CSV_headers)
    writer.writerows(prod_data)

Я протестировал его, повторив текущий список URL-адресов 10 раз, это заняло больше времени, чем я ожидал. Несомненно, необходимо внести улучшения, я мог бы переписать его для использования l xml в ближайшие несколько дней, и многопроцессорная обработка также может быть хорошим вариантом. Конечно, все зависит от того, как вы это используете:)

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