ตัวเลือก Bs4: ขูดอเมซอนโดยใช้ซุปที่สวยงาม

ฉันกำลังพยายามขูดไซต์ที่มีลิงก์ไปยัง Amazon ด้วย Python โดยใช้เฟรมเวิร์กเหล่านี้ - ซีลีเนียม ซุปที่สวยงาม

เป้าหมายของฉันคือการขูดรายละเอียดผลิตภัณฑ์ของ Amazon ต่อไปนี้ -> ชื่อ ราคา คำอธิบาย รีวิวครั้งแรก

แต่ฉันมีช่วงเวลาที่ยากลำบากกับตัวเลือกที่สวยงาม ฉันลองใช้หลายชุดผสมกัน แต่ฉันได้ผลลัพธ์เป็นโมฆะหรือข้อผิดพลาด น่าเสียดายที่ไม่ใช่แบบมืออาชีพ ปัญหาหลักคือ Beautiful Soup ไม่มีตัวเลือก XPath (AFAIK) ฉันควรย้ายไปที่ scrapy สำหรับงานนี้ หรือว่า Scrapy มีมากเกินไปสำหรับ Scraper ธรรมดานี้

นี่เป็นผลิตภัณฑ์แรกที่ฉันจะทำซ้ำในภายหลัง

from bs4 import BeautifulSoup
from selenium import webdriver
import time

driver.get('https://www.example.com')
driver.get('https://www.example.com')
first_article = driver.find_element_by_css_selector('div.button')
first_article.click()
html = driver.page_source
soup = BeautifulSoup(html, 'lxml')
# perform the operation

หลังจากนั้นฉันต้องเลือกเส้นทางที่เกี่ยวข้อง แต่จะทำอย่างไร? ใน Xpath จะเป็นเช่นนี้

Title = '//h1[@id="title"]//text()'

Price = '//span[contains(@id,"ourprice") or contains(@id,"saleprice")]/text()'

Category = //a[@class="a-link-normal a-color-tertiary"]//text()'

แต่รายละเอียดสินค้าและเส้นทางสู่การรีวิวครั้งแรกเท่านั้นที่ยังทำไม่ได้ ฉันคิดว่าตัวเลือก Beautiful Soup find_all จะไม่มีประโยชน์ที่นี่


person Abhijeet Pal    schedule 08.06.2018    source แหล่งที่มา
comment
ลอง lxml   -  person ᴘᴀɴᴀʏɪᴏᴛɪs    schedule 08.06.2018
comment
ฉันลองสิ่งนี้ด้วย lxml html = driver.page_source soup.xpath('//*[@id="title"]') soup.xpath('//*[@id="title"]') แต่ได้รับข้อผิดพลาดนี้ --› วัตถุ 'NoneType' ไม่สามารถเรียกได้ เหตุใดวัตถุจึงไม่สามารถเรียกได้   -  person Abhijeet Pal    schedule 08.06.2018


คำตอบ (4)


หากจุดประสงค์ของคุณเป็นเพียงการขูดเว็บไซต์ เลือกใช้ BeautifulSoup สิ่งนี้จะช่วยคุณประหยัดเวลาในการดำเนินการและบรรทัดโค้ดเพิ่มเติมเมื่อเปรียบเทียบกับการใช้ Selenium

BeautifulSoup มีฟังก์ชันชื่อ findNext จากองค์ประกอบปัจจุบันที่มุ่งเป้าไปที่เด็ก ดังนั้น:

ลองสิ่งนี้-

    import bs4 
    import requests

    res = requests.get(url)
    soup = bs4.BeautifulSoup(self.res.text, "lxml")    #lxlm parser
    text = soup.findNext('div',{'class':'class_value'}).findNext('div',{'id':'id_value'}).findAll('a') 

สิ่งนี้คล้ายกับ xpath -

div[class=class_value]/div[id=id_value]
person Saurav    schedule 08.06.2018

ลองใช้ซีลีเนียมซึ่งรองรับตัวเลือก xpath driver.find_element_by_xpath(หัวข้อ) # ตัวอย่าง

person Goran    schedule 08.06.2018
comment
คุณชาย ฉันลองใช้สิ่งนี้กับชื่อผลิตภัณฑ์ driver.find_element_by_xpath('//*[@id="productTitle"]') แต่ได้รับข้อผิดพลาด - ไม่สามารถค้นหาได้ - person Abhijeet Pal; 08.06.2018

คุณสามารถใช้ BeautifulSoup เพื่อสิ่งนั้นได้ มันไม่ยากจริงๆ และหากคุณสนใจ ฉันคิดว่ามี API สำหรับสิ่งนั้น

ซีลีเนียมถูกใช้บ่อยกว่าในการคลิกปุ่ม และอาจทำให้โปรแกรมของคุณช้าลง เนื่องจากการคลิกปุ่มแต่ละปุ่ม คุณจะต้องรอหน้าโหลด และสำหรับสิ่งที่คุณต้องทำ คุณจะต้องมีความเร็ว เพราะมันเยอะมาก ของลิงค์ :D.

มีเอกสารที่ดีเกี่ยวกับ BeautifulSoup: http://www.pythonforbeginners.com/beautifulsoup/beautifulsoup-4-python

Api ที่ดีสำหรับหลาม: aws.amazon.com/python

person Joao Pedro Lopes Mendes    schedule 08.06.2018
comment
หน้าแรกคือหน้า JavaScript ฉันต้องการซีลีเนียมเพื่อคลิกปุ่ม - person Abhijeet Pal; 08.06.2018
comment
จากนั้นใช้สแครป - person Joao Pedro Lopes Mendes; 08.06.2018
comment
มีเหตุผลอะไรไหม? เพราะฉันต้องใช้ซีลีเนียมที่นั่นเช่นกัน Splash ไม่ทำงานบนเครื่องของฉัน - person Abhijeet Pal; 08.06.2018
comment
ลองค้นหาของ amazon api ฉันไม่รู้ว่ามี api ใด ๆ หรือไม่ แต่ก็คุ้มค่ากับการยิง: D - person Joao Pedro Lopes Mendes; 08.06.2018
comment
Scrapy เป็นวิธีที่ดีที่สุดในการทำสิ่งนี้ - person Joao Pedro Lopes Mendes; 08.06.2018

Amazon มีกลไกป้องกันการขูด ซึ่งหากตรวจพบการขูด จะใช้ captcha บนที่ขูด ดังนั้นปัญหาของคุณคือส่งคืน html สำหรับ captcha และคุณไม่พบสิ่งใดเลย

วิธีเดียวที่เชื่อถือได้ในการขูดอเมซอนคือการใช้ซีลีเนียมเวอร์ชันไม่มีหัว

person Dennis Cafiero    schedule 29.05.2019