使用网页抓取来检查物品是否有库存



我正在创建一个Python程序,该程序使用web抓取来检查物品是否有库存。该代码是一个Python 3.9脚本,使用Beautiful Soup 4并请求抓取物品的可用性。我最终想让程序搜索多个网站和每个网站中的多个链接,这样我就不必一次运行一堆脚本了。该程序的预期结果是:
200
0
In Stock
但我得到的是:
200
[]
Out Of Stock

"200"表示代码是否可以访问服务器,200是预期结果。"0"是一个布尔值,用于查看项目是否有库存,预期响应为"0"(库存(。我已经给出了库存项目和缺货项目,它们都给出了200 [] Out Of Stock的相同响应。我有一种感觉,def check_item_in_stock中的out_of_stock_divs有问题,因为这就是我得到[]的结果,因为它找到了项目的可用性

昨天早些时候,我让代码正常工作,我不断添加功能(比如抓取多个链接和不同的网站(,这破坏了它,我无法将其恢复到工作状态

这是程序代码。(我确实根据Arya Boudaie先生在他的网站上的代码编写了这个代码,https://aryaboudaie.com/不过,我取消了他的短信通知,因为我计划在旁边的一台备用电脑上运行,并让它大声播放,这将在以后实施。(

from bs4 import BeautifulSoup
import requests
def get_page_html(url):
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"}
page = requests.get(url, headers=headers)
print(page.status_code)
return page.content

def check_item_in_stock(page_html):
soup = BeautifulSoup(page_html, 'html.parser')
out_of_stock_divs = soup.findAll("text", {"class": "product-inventory"})
print(out_of_stock_divs)
return len(out_of_stock_divs) != 0
def check_inventory():
url = "https://www.newegg.com/hp-prodesk-400-g5-nettop-computer/p/N82E16883997492?Item=9SIA7ABC996974"
page_html = get_page_html(url)
if check_item_in_stock(page_html):
print("In stock")
else:
print("Out of stock")
while True:
check_inventory()
time.sleep(60)```

产品库存状态位于<div>标签内,而不是<text>标签:

import requests
from bs4 import BeautifulSoup

def get_page_html(url):
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"}
page = requests.get(url, headers=headers)
print(page.status_code)
return page.content

def check_item_in_stock(page_html):
soup = BeautifulSoup(page_html, 'html.parser')
out_of_stock_divs = soup.findAll("div", {"class": "product-inventory"})  # <--- change "text" to div
print(out_of_stock_divs)
return len(out_of_stock_divs) != 0
def check_inventory():
url = "https://www.newegg.com/hp-prodesk-400-g5-nettop-computer/p/N82E16883997492?Item=9SIA7ABC996974"
page_html = get_page_html(url)
if check_item_in_stock(page_html):
print("In stock")
else:
print("Out of stock")
check_inventory()

打印:

200
[<div class="product-inventory"><strong>In stock.</strong></div>]
In stock

注意:该网站的HTML标记可能在过去发生了变化,我会修改check_item_in_stock函数:

def check_item_in_stock(page_html):
soup = BeautifulSoup(page_html, 'html.parser')
out_of_stock_div = soup.find("div", {"class": "product-inventory"})
return out_of_stock_div.text == "In stock."

使用lxml库,您可能可以以可读性很强、稍微优雅一点的方式完成跑腿工作:

import config
import requests
from lxml import html
def in_stock(url: str = config.upstream_url) -> tuple:
""" Check the website for stock status """
page = requests.get(url, headers={'User-agent': config.user_agent})
proc_html = html.fromstring(page.text)
checkout_button = proc_html.get_element_by_id('addToCart')
return (page.status, not ('disabled' in checkout_button.attrib['class']))

我建议使用xpath来标识页面上要检查的元素。这使得在上游网站更新(超出您的控制范围(的情况下很容易更改,因为您只需要调整xpath字符串以反映上游更改:

# change me, if upstream web content changes
xpath_selector = r'''///button[@id='addToCart']'''
checkout_button = proc_html.xpath(xpath_selector)[0]

顺便说一句,从风格上讲,一些纯粹主义者建议在编写函数时避免副作用(即在函数中使用print()(。您可以返回一个包含状态代码和结果的元组。这是Python中一个非常好的特性。

也许你已经知道了,但Git是你的朋友。无论何时您进行更改,都可以将其推送到github或您选择保存的任何位置。其他人可以克隆它,他们将拥有您编写的代码,因此如果多次克隆,则可以在多个位置检索它。

最新更新