【问题标题】:bs4 parses different html than browserbs4 解析与浏览器不同的 html
【发布时间】:2020-04-13 20:44:37
【问题描述】:

我正在尝试使用 Beautifulsoup4 抓取 farefetch.com (https://www.farfetch.com/ch/shopping/men/sale/all/items.aspx?page=1&view=180&scale=282),但我无法找到 已解析 文本(转储到soup.html) 就像在浏览器中的开发工具视图中一样(使用 CTRL + F 搜索匹配的字符串时)。

我的代码没有任何问题,但毫无疑问是:

#!/usr/bin/python 
# imports
import bs4
import requests
from bs4 import BeautifulSoup as soup

# parse website
url = 'https://www.farfetch.com/ch/shopping/men/sale/all/items.aspx?page=1&view=180&scale=282'
response = requests.get(url)
page_html = response.text
page_soup = soup(page_html, "html.parser")

# write parsed soup to file
with open("soup.html", "a") as dumpfile:
    dumpfile.write(str(page_soup))

当我将soup.html 文件拖到浏览器中时,所有内容都会按原样加载(就像真实的url)。我认为这是对解析的某种保护?我试图放入一个连接标头,它告诉另一端的网络服务器我正在从真正的浏览器请求这个,但它也没有工作。

  1. 以前有没有人遇到过类似的情况?
  2. 有没有办法获得浏览器中显示的真实 html?

当我在浏览器中搜索想要的内容时,它(显然)出现了......

这里将解析后的 html 保存为“soup.html”。无论如何我搜索 (CTRL+F) 或 bs4 函数 find_all() 或 find() 或其他任何方法,都找不到我要查找的内容。

【问题讨论】:

  • 该页面几乎可以肯定地使用 Javascript 来动态操作 DOM 对象(添加类、样式、标签..) - 而BeautifulSoup 不执行 JavaScript。您需要从页面中获取哪些信息?
  • 在“网络”面板中搜索。这会告诉你它是否真的在回应中。
  • 嗨,安德烈,感谢您的回答。我想为每个在售(折扣)的产品解析产品参数(如名称、图片链接、详细信息页面链接、价格等)......关于如何实现这一点的任何想法? @AndrejKesely

标签: python-3.x web-scraping web-applications beautifulsoup html-parsing


【解决方案1】:

根据您的评论,下面是一个示例,您可以如何从打折的产品中提取一些信息:

import requests
from bs4 import BeautifulSoup

url = "https://www.farfetch.com/ch/shopping/men/sale/all/items.aspx?page=1&view=180&scale=282"

soup = BeautifulSoup(requests.get(url).text, 'html.parser')

for product in soup.select('[data-test="productCard"]:has([data-test="discountPercentage"])'):

    link = 'https://www.farfetch.com' + product.select_one('a[itemprop="itemListElement"][href]')['href']
    brand = product.select_one('[data-test="productDesignerName"]').get_text(strip=True)
    desc = product.select_one('[data-test="productDescription"]').get_text(strip=True)
    init_price = product.select_one('[data-test="initialPrice"]').get_text(strip=True)
    price = product.select_one('[data-test="price"]').get_text(strip=True)
    images = [i['content'] for i in product.select('meta[itemprop="image"]')]

    print('Link          :', link)
    print('Brand         :', brand)
    print('Description   :', desc)
    print('Initial price :', init_price)
    print('Price         :', price)
    print('Images        :', images)
    print('-' * 80)

打印:

Link          : https://www.farfetch.com/ch/shopping/men/dashiel-brahmann-printed-button-up-shirt-item-14100332.aspx?storeid=9359
Brand         : Dashiel Brahmann
Description   : printed button up shirt
Initial price : CHF 438
Price         : CHF 219
Images        : ['https://cdn-images.farfetch-contents.com/14/10/03/32/14100332_22273147_300.jpg', 'https://cdn-images.farfetch-contents.com/14/10/03/32/14100332_22273157_300.jpg']
--------------------------------------------------------------------------------
Link          : https://www.farfetch.com/ch/shopping/men/dashiel-brahmann-corduroy-t-shirt-item-14100309.aspx?storeid=9359
Brand         : Dashiel Brahmann
Description   : corduroy T-Shirt
Initial price : CHF 259
Price         : CHF 156
Images        : ['https://cdn-images.farfetch-contents.com/14/10/03/09/14100309_21985600_300.jpg', 'https://cdn-images.farfetch-contents.com/14/10/03/09/14100309_21985606_300.jpg']
--------------------------------------------------------------------------------

... and so on.

【讨论】:

    【解决方案2】:

    以下对我有帮助:
    而不是下面的代码

    page_soup = soup(page_html, "html.parser")
    

    使用

    page_soup = soup(page_html, "html")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-05
      • 2013-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多