美丽汤无法按类找到 HTML 元素



这是我试图用Python抓取的网站:

https://www.ebay.de/sch/i.html?_from=R40&_nkw=iphone+8&_sacat=0&LH_Sold=1&LH_Complete=1&rt=nc&LH_ItemCondition=3000

我想使用"srp-results srp-list clearfix"类访问"ul"元素。这是我对请求和美丽汤的尝试:

from bs4 import BeautifulSoup
import requests
url = 'https://www.ebay.de/sch/i.html?_from=R40&_nkw=iphone+8&_sacat=0&LH_Sold=1&LH_Complete=1&rt=nc&LH_ItemCondition=3000'
r = requests.get(url)
soup = BeautifulSoup(r.text, 'html.parser')
uls = soup.find_all('ul', attrs = {'class': 'srp-results srp-list clearfix'})

并且输出始终为空字符串。 我还尝试使用Selenium网络驱动程序抓取网站,并得到了相同的结果。

首先,我对你的错误有点困惑,但经过一些调试后,我发现: eBay使用JavaScript动态生成ul

因此,由于您无法使用BeautifulSoup执行JavaScript,因此您必须使用selenium并等到JavaScript加载该ul

这可能是因为您要查找的内容是由JavaScript呈现的 在 Web 浏览器上加载页面后,这意味着 Web 浏览器在运行 javascript 后加载该内容,而您无法通过 requests.get 请求从 python 获取该内容。

我建议学习硒来抓取你想要的数据

空输出可能是由于错误的类,也可能是由于未指定以何种形式显示信息。

如果将requests用作requests库中的默认user-agent则原因也可能是请求被阻止python-requests。 eBay没有使用Javascript渲染页面,至少目前是这样。

另一个步骤可能是 旋转user-agent,例如,在 PC、手机和平板电脑之间切换,以及在浏览器(例如 Chrome、火狐、Safari、Edge 等(之间切换。

您可以在页面上找到必要的元素,以使用 SelectorGadget Chrome 扩展程序进行解析,通过单击浏览器中的所需元素轻松选择选择器,如果页面正在使用 JS,这并不总是完美运行(在这种情况下我们可以(。

在线 IDE 中所有可能页面的分页代码示例。

from bs4 import BeautifulSoup
import requests, lxml
import json
# https://requests.readthedocs.io/en/latest/user/quickstart/#custom-headers
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36"
}

params = {
'_nkw': 'iphone+8',      # search query  
'LH_Sold': '1',          # shows sold items
'_pgn': 1                # page number
}
data = []
while True:
page = requests.get('https://www.ebay.de/sch/i.html', params=params, headers=headers, timeout=30)
soup = BeautifulSoup(page.text, 'lxml')

print(f"Extracting page: {params['_pgn']}")
print("-" * 10)

for products in soup.select(".s-item__pl-on-bottom"):
title = products.select_one(".s-item__title span").text
price = products.select_one(".s-item__price").text
try:
sold_date = products.select_one(".s-item__title--tagblock .POSITIVE").text
except:
sold_date = None

data.append({
"title" : title,
"price" : price,
"sold_date": sold_date
})
if soup.select_one(".pagination__next"):
params['_pgn'] += 1
else:
break
print(json.dumps(data, indent=2, ensure_ascii=False))

示例输出:

[
{
"title": "Apple iPhone 8 - 64 GB- Rose Gold und viele mehr(Ohne Simlock)",
"price": "EUR 91,00",
"sold_date": "Verkauft  22. Feb 2023"
},
{
"title": "iPhone 8 64GB Produkt rot - Ersatzteile & Reparaturen",
"price": "EUR 17,03",
"sold_date": "Verkauft  22. Feb 2023"
},
{
"title": "iPhone 8 64GB Spacegrau - Ersatzteile & Reparaturen",
"price": "EUR 17,03",
"sold_date": "Verkauft  22. Feb 2023"
},
other results ...
]

作为替代方案,您可以使用SerpApi的Ebay Organic Results API。这是一个付费 API,带有免费计划,可以处理后端的块和解析。

带分页的示例代码:

from serpapi import EbaySearch
import json
params = {
"api_key": "...",                 # serpapi key, https://serpapi.com/manage-api-key   
"engine": "ebay",                 # search engine
"ebay_domain": "ebay.de",         # ebay domain
"_nkw": "iphone+8",               # search query
"_pgn": 1                         # pagination
# "LH_Sold": "1"                    # shows sold items
}
search = EbaySearch(params)        # where data extraction happens
page_num = 0
data = []
while True:
results = search.get_dict()     # JSON -> Python dict
if "error" in results:
print(results["error"])
break

for organic_result in results.get("organic_results", []):
title = organic_result.get("title")
price = organic_result.get("price")
data.append({
"price" : price,
"title" : title
})

page_num += 1
print(page_num)

if "next" in results.get("pagination", {}):
params['_pgn'] += 1
else:
break
print(json.dumps(data, indent=2, ensure_ascii=False))

输出:

[
{
"price": {
"raw": "EUR 123,75",
"extracted": 123.75
},
"title": "Apple iPhone 8 64GB 128GB 256GB Unlocked Space Grey Gold Silver Red 4G | Good"
},
{
"price": {
"raw": "EUR 137,85",
"extracted": 137.85
},
"title": "Apple iPhone 8 - 64GB - All Colors - Unlocked - Good Condition"
},
other results ...
]

如果您想了解有关网站抓取的更多信息,有 13 种方法可以从任何网站博客文章中抓取任何公共数据。

最新更新