【问题标题】:My python script only pulls the first result then moves on to the next url我的 python 脚本只提取第一个结果,然后转到下一个 url
【发布时间】:2018-01-26 17:45:14
【问题描述】:

我正在为一个网站创建一个 python 爬虫来获取价格、产品编号、猫号、描述。当我运行这个脚本时,它只会拉出页面的第一项,然后移动到下一个 url。 python 新手只是想知道如何修改以从页面中提取所有产品。感谢澄清第一个网址上只有一个产品,但第二个第三个都有许多没有被拉出的产品。

 import requests
from bs4 import BeautifulSoup
import random
import time

product_urls = [
'https://www.qiagen.com/us/shop/pcr/primer-sets/miscript-precursor-assays/#orderinginformation',
'https://www.qiagen.com/us/shop/pcr/primer-sets/miscript-primer-assay-plate/#orderinginformation',
'https://www.qiagen.com/us/shop/pcr/primer-sets/miscript-primer-assays/#orderinginformation', 
]

for URL in product_urls:
    page = requests.get(URL)
    soup = BeautifulSoup(page.text,"lxml")
    timeDelay = random.randrange(5, 25)

    for item in soup.select('.content'):
        cat_name = item.select_one('.title').text.strip()
        cat_discription = item.select_one('.copy').text.strip()
        product_name = (item.find('div',{'class':'headline'}).text.strip())
        product_discription = (item.find('div',{'class': 'copy'}).text.strip())
        product_number = (item.find('td',{'class': 'textLeft paddingTopLess'}).text.strip())
        cat_number = (item.find('td',{'class': 'textRight paddingTopLess2'}).text.strip())
        product_price = (item.find('span',{'class': 'prc'}).text.strip())
        print("Catagory Name: {}\n\nCatagory Discription:  {}\n\nProduct Name:  {}\n\nProduct Discription:  {}\n\nProduct Number:  {}\n\nCat No:  {}\n\nPrice:  {}\n\n".format(cat_name,cat_discription,product_name,product_discription,product_number,cat_number,product_price))
        time.sleep(timeDelay)

【问题讨论】:

  • soup.select('.content') 是否返回不止一项?
  • soup.select('.container') 只产生这个。
  • 检查您的任何finds 是否返回None
  • 类别名称:miScript Precursor Assays 类别描述:miScript Precursor Assays areprecursor-miRNA– 产品名称:高级搜索设置 产品描述:miScript Precursor Assays areprecursor-miRNA– 产品编号:货号:可变价格: $91.80
  • 似乎在每个网页上,只列出了一个结果与提到的产品信息。您是否要在页面右栏中抓取所有套件的产品列表?

标签: python web-scraping tags


【解决方案1】:

您可以从pane 类 div 中获取表格元素。第 4 个表是主要产品,第 5 个(如果存在)是附加产品。

在以下示例中,我使用列表推导来输出包含标题、描述、产品 n°、类别 n° 和价格的元组列表:

from bs4 import BeautifulSoup
import requests

product_urls = [
    'https://www.qiagen.com/us/shop/pcr/primer-sets/miscript-precursor-assays/#orderinginformation',
    'https://www.qiagen.com/us/shop/pcr/primer-sets/miscript-primer-assay-plate/#orderinginformation',
    'https://www.qiagen.com/us/shop/pcr/primer-sets/miscript-primer-assays/#orderinginformation', 
    'https://www.qiagen.com/us/shop/pcr/real-time-pcr-enzymes-and-kits/miscript-target-protectors/#orderinginformation',
    'https://www.qiagen.com/us/shop/pcr/real-time-pcr-enzymes-and-kits/two-step-qrt-pcr/miscript-sybr-green-pcr-kit/#orderinginformation'
]

session = requests.Session()

for URL in product_urls:

    response = session.get(URL)
    soup = BeautifulSoup(response.content, "html.parser")

    tables = soup.find_all("div", {"class":"pane"})[0].find_all("table")

    if (len(tables) > 4):
        product_list = [
            (
                t[0].findAll("div", {"class":"headline"})[0].text.strip(), #title
                t[0].findAll("div", {"class":"copy"})[0].text.strip(),     #description
                t[1].text.strip(),                                         #product number
                t[2].text.strip(),                                         #category number
                t[3].text.strip()                                          #price
            )
            for t in (t.find_all('td') for t in tables[4].find_all('tr'))
            if t
        ]
    elif (len(tables) == 1):
        product_list = [
            (
                t[0].findAll("div", {"class":"catNo"})[0].text.strip(),    #catNo
                t[0].findAll("div", {"class":"headline"})[0].text.strip(), #headline
                t[0].findAll("div", {"class":"price"})[0].text.strip(),    #price
                t[0].findAll("div", {"class":"copy"})[0].text.strip()      #description
            )
            for t in (t.find_all('td') for t in tables[0].find_all('tr'))
            if t
        ]
    else:
        print("could not parse main product")

    print(product_list)

    if len(tables) > 5:
        add_product_list = [
            (
                t[0].findAll("div", {"class":"title"})[0].text.strip(), #title
                t[0].findAll("div", {"class":"copy"})[0].text.strip(),  #description
                t[1].text.strip(),                                      #product number
                t[2].text.strip(),                                      #category number
                t[3].text.strip()                                       #price
            )
            for t in (t.find_all('td') for t in tables[5].find_all('tr'))
            if t
        ]
        print(add_product_list)

如果要将元组索引转换为每个字段的单个列表,请选中 this answer

【讨论】:

  • 非常感谢,这很有帮助。作为仍在尝试更详细地学习python的人,您是如何找到表格的编号的?你只是数了数并把它们整理好了。知道这对您来说一定是一个非常简单的问题。
  • 是的,我数过了,我没有找到任何可以准确识别它们的父类/ID,但是如果您找到更具体的方法来找到它们,它也会这样做
  • 非常感谢,这非常有帮助,感谢您提供的链接。我有一个问题,您是如何得出表 [4] 等表的编号的?对 python 来说还是很新,所以只是想确保我理解所有的步骤。
  • @user9269112 在 Chrome 开发人员工具中使用检查器,您可以通过选择在识别要抓取的内容时有用的项目来查看元素。在上面的脚本中,您观察第一个具有“pane”类的 div 并查找其中的所有表格元素。我注意到当没有显示附加产品时有 4 个表格,当存在附加产品时有第 5 个表格
  • 太棒了!我必须考虑使用 chrome 我一直在为这个项目使用 Firefox。还有一个问题很抱歉,如果它很简单,但我想在这个脚本中添加更多的 url,但是得到一个超出范围的索引错误是因为表设置为 > 5?
猜你喜欢
  • 2020-04-27
  • 2018-06-01
  • 2011-07-27
  • 2021-07-14
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-08
相关资源
最近更新 更多