繁体   English   中英

我可以抓取单个 ebay 列表的标题,但我无法抓取页面上的每个标题 (Python/BeautifulSoup/lxml)

[英]I can scrape a title of a single ebay listing, but am having trouble scraping every single title on the page (Python/BeautifulSoup/lxml)

我正在尝试抓取 ebay 页面上每件商品的标题。 这是页面。 我首先尝试抓取第一个列表的标题(我的代码的第 5-7 行),并且我成功了,因为第一个列表的标题被打印出来了。 但是当我尝试抓取 ebay 页面上的每个标题时(第 8-10 行),没有任何内容被打印出来。 我的逻辑有缺陷吗? 谢谢!

1. from bs4 import BeautifulSoup
2. import requests
3. source = requests.get("https://www.ebay.com/sch/i.html?_from=R40&_trksid=p2380057.m570.l1313&_nkw=hippo&_sacat=0").text
4. soup = BeautifulSoup(source, "lxml")
5. listing = soup.find("li", class_=("s-item    s-item--watch-at-corner"))
6. title = soup.find("h3", class_=("s-item__title")).text
7. print(title)
8. for listing in soup.find_all("li", class_=("s-item    s-item--watch-at-corner")):
9.    title = soup.find("h3", class_=("s-item__title")).text
10.   print(title)

您每次都在汤上调用find("h3", class_=("s-item__title") ,您需要在循环中的每个列表上调用它,否则它将始终获取第一个标题。另外,请记住无论出于何种原因,eBay 页面上都有一些隐藏的结果,也许可以检查一下,看看是否要忽略或也包含这些结果。我在循环中添加了 enumerate 函数只是为了跟踪结果的数量。

我使用这个选择器来查找 chrome 开发工具li.s-item.s-item--watch-at-corner h3.s-item__title上的所有列表

from bs4 import BeautifulSoup
import requests

source = requests.get("https://www.ebay.com/sch/i.html?_from=R40&_trksid=p2380057.m570.l1313&_nkw=hippo&_sacat=0").text
soup = BeautifulSoup(source, "lxml")
listing = soup.find("li", class_=("s-item    s-item--watch-at-corner"))
title = soup.find("h3", class_=("s-item__title")).text
print(title)
for i, listing in enumerate(soup.find_all("li", class_=("s-item s-item--watch-at-corner"))):
    title = listing.find("h3", class_=("s-item__title")).text
    print("[{}] ".format(i) + title)

结果:

    [0] Pewter Hippopotamus Hippo  Figurine 
    [1] Hippopotamus Figurine 1.5" Gemstone Opalite Crystal Healing Carved Statue Decor 
    [2] hippopotamus coffee cafe picture animal hippo art tile gift
    [3] NEW! Miniature Bronze Hippo Figurine Miniature Bronze Statue Animal Collectible
    [4] Hippopotamus Gzhel porcelain figurine hippo handmade
    [5] Hippopotamus Gzhel porcelain figurine hippo souvenir handmade and hand-painted
....

快速浏览文档后

BeautifulSoup 的 .find_all() 方法返回一个列表(正如人们所期望的)。 但是,在我看来,for 循环中的 .find() 只是再次查询响应,而不是对您生成的列表进行处理。 我希望手动提取标题,例如:

 title = listing['some_property']

或者您正在使用的库可能提供了另一种方法。

通过查看代码,您还没有检查类的类型。

from bs4 import BeautifulSoup
import requests
source=requests.get("https://www.ebay.com/sch/i.html_from=R40&_trksid=p2380057.m570.l1313&_nkw=hippo&_sacat=0").text
soup = BeautifulSoup(source, "lxml")
listing = soup.find("li", class_=("s-item    s-item--watch-at-corner"))
title = soup.find("h3", class_=("s-item__title")).text
print(type(listing))

这将返回结果

<class 'NoneType'>

所以解析结束,因为没有 li 标签可以找到

查看SelectorGadget Chrome 扩展程序,通过单击浏览器中的所需元素轻松选择选择器,如果页面大量使用 JS(在这种情况下我们可以),这并不总是完美工作。

如果在requests库中使用requests作为默认user-agentpython-requests ,也有可能阻止请求。

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

online IDE

from bs4 import BeautifulSoup
import requests, json, lxml

# 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': 'hippo',              # search query  
}

data = []

page = requests.get('https://www.ebay.com/sch/i.html', params=params, headers=headers, timeout=30)
soup = BeautifulSoup(page.text, 'lxml')
    
for title in soup.select(".s-item__title span"):
    if "Shop on eBay" in title:
        pass
    else:
        data.append({"title" : title.text})
 
print(json.dumps(data, indent=2, ensure_ascii=False))

示例 output:

[
  {
    "title": "Hippopotamus Gzhel porcelain figurine hippo souvenir handmade and hand-painted"
  },
  {
    "title": "Coad Peru Signed 1 1/2\" HIPPO Clay Pottery Collectible Figurine"
  },
  {
    "title": "Glass Hippo Hippopotamus figurine \"murano\" handmade"
  },
  {
    "title": "2 Hand Carved Soapstone Brown Hippopotamus Hippo Animal Figurine Paperweight"
  },
  {
    "title": "Schleich Hippo D-73527 Hippopotamus Mouth Open Wildlife Toy Figure 2012"
  },
  # ...
]

或者,您可以使用 SerpApi 的Ebay Organic Results API。 这是一个付费的 API 和一个在后端处理块和解析的免费计划。

示例代码:

from serpapi import EbaySearch
import os, json

params = {
    "api_key": os.getenv("API_KEY"),  # serpapi api key    
    "engine": "ebay",                 # search engine
    "ebay_domain": "ebay.com",        # ebay domain
    "_nkw": "hippo"                   # search query                
}

search = EbaySearch(params)        # where data extraction happens

data = []

results = search.get_dict()     # JSON -> Python dict

for organic_result in results.get("organic_results", []):
    title = organic_result.get("title")
    
    data.append({
      "title" : title      
    })
      
print(json.dumps(data, indent=2))

Output:

[
   {
    "title": "Schleich Hippo D-73527 Hippopotamus Mouth Open Wildlife Toy Figure 2012"
  },
  {
    "title": "Vintage WOODEN SCULPTURE Hippo HIPPOPOTAMUS"
  },
  {
    "title": "Hippopotamus Gzhel porcelain figurine hippo souvenir handmade and hand-painted"
  },
  {
    "title": "Glass Hippo Hippopotamus figurine \"murano\" handmade"
  },
  # ...
]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM