【问题标题】:Problem Scraping newegg.ca with Beautiful Soup用 Beautiful Soup 抓取 newegg.ca 的问题
【发布时间】:2019-07-14 23:28:39
【问题描述】:

我过去曾搜索过几个网站,但 newegg.ca 的结构与其他网站不同。我使用 BeautifulSoup 仅提取产品的名称和价格。 我要抓取的网站是https://www.newegg.ca/p/N82E16875606157

到目前为止,我已经使用以下方法刮掉了标题:

page = requests.get(URL, headers=headers)
page_soup = BeautifulSoup(page.content, "html.parser")

global ng_title
ng_title = page_soup.find(id="grpDescrip_h").get_text().strip()
print(ng_title)

输出:

Huawei P30 4G LTE Cell Phone 6.1" Breathing Crystal 128GB 6GB RAM

但我在提取价格时遇到了困难。也许我需要实现一个 for 循环?或者还有其他方法。

感谢您的帮助,谢谢!

【问题讨论】:

    标签: python html web-scraping beautifulsoup


    【解决方案1】:

    正如其他答案所提到的,这基本上是因为页面内容是通过 JavaScript 加载的,而在 urlopener 或请求的帮助下获取源代码不会加载该动态部分。

    所以在这里我有一个解决方法,实际上你可以利用 selenium 让动态内容加载,然后从那里获取源代码并使用 BeautifulSoup 解析它。在浏览器解析完完整的源代码后,您可以随心所欲地使用它。这是实际给出您预期结果的代码。但是你需要设置selenium web driver

    from lxml import html
    from bs4 import  BeautifulSoup
    from time import sleep
    from selenium import webdriver
    
    
    def parse(url):
        response = webdriver.Firefox()
        response.get(url)
        sleep(3)
        sourceCode=response.page_source
        return  sourceCode
    
    
    year =2019
    soup = BeautifulSoup(parse("https://www.newegg.ca/p/N82E16875606157"),'lxml')
    ##Do with whatever you want with the source code
    

    【讨论】:

      【解决方案2】:

      你不需要硒,价格就在 HTML 中!
      在你拿出大手笔之前,先尝试检查 HTML。使用Ctrl + U查看页面源然后Ctrl + F搜索价格949,你会看到价格:

      <div itemprop='offers' itemscope itemtype='//schema.org/Offer'>
                                      <meta itemprop='price' content='949.00' />
                                      <meta itemprop='priceCurrency' content='CAD' />
                                    </div>
      

      然后:

      import requests
      from bs4 import BeautifulSoup
      
      url = 'https://www.newegg.ca/p/N82E16875606157'
      res = requests.get(url)
      res.raise_for_status()
      html = res.text
      soup = BeautifulSoup(html, 'html.parser')
      price = float(soup.select_one('[itemprop=price]')['content'])
      print(price)
      

      输出:

      949.0
      

      【讨论】:

        【解决方案3】:

        我在想一个更简单的解决方案是 selenium 而不是像这样的 bs4,

        from lxml import html
        from time import sleep
        from selenium import webdriver
        
        
        def parse(url):
            response = webdriver.Chrome()
            response.get(url)
            sleep(3)
            name = response.find_element_by_xpath(' //*[@id="grpDescrip_75-606-157"]')
            price = response.find_element_by_xpath(' //*[@id="landingpage-price"]/div/div/ul/li[3]')
            details = response.find_element_by_xpath(' //*[@id="synopsis"]/div[4]/div/div[9]/ul')
        
        
            print(name.text)
            print(price.text)
            print(details.text)
        
        
        
            sleep(1)
        
        
        if __name__ == '__main__':
        
            parse('https://www.newegg.ca/p/N82E16875606157')
        

        你怎么看?

        【讨论】:

        • 看起来不错。我仍在努力让硒在我的无头 ubuntu 上工作:S
        • 我一直在检查 newegg 手机,xpath 选择器对于任何型号的手机都是相同的价格,细节和名称选择器仅因库存项目而异。因此,您应该能够编写一个脚本来提取一系列库存编号,然后使用 for 循环对其进行批处理。 IE 苹果 iphone 选择器是 //*[@id="grpDescrip_75-100-569"] ,其中 75-100-569 是库存号。祝你好运!
        【解决方案4】:

        我放弃了尝试使用 qtwebkit,因为他们已弃用它并且无法轻松安装。

        在 Chuck LaPress 的建议下,我研究了 selenium,并努力让它在 ubuntu server 18 上运行。最后它变得非常简单:

        sudo apt install chromium-browser
        sudo apt install chromium-chromedriver
        pip install lxml selenium
        

        那么下面的代码就可以了!

        from selenium import webdriver
        from time import sleep
        
        options = webdriver.ChromeOptions()
        options.binary_location = '/usr/bin/chromium-browser'
        options.add_argument("headless")
        
        driver = webdriver.Chrome(options=options)
        
        url = 'https://www.newegg.ca/p/N82E16875606157'
        driver.get(url);
        sleep(3)
        
        name = driver.find_element_by_css_selector("#grpDescrip_h span")
        price = driver.find_element_by_css_selector("#landingpage-price .price-current")
        
        print(name.text)
        print(price.text)
        

        【讨论】:

        • 好的,试过了还是不行。不幸的是,该页面正在使用 javascript 呈现。
        • 对。所以我假设没有直接的方法可以做到这一点?
        猜你喜欢
        • 2019-12-23
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 2022-08-22
        • 2020-07-27
        • 1970-01-01
        相关资源
        最近更新 更多