【问题标题】:Web scraping returning empty dictionary网页抓取返回空字典
【发布时间】:2021-10-01 22:54:48
【问题描述】:

我正在尝试使用 Python-Selenium 从该网站https://ricetta.it/ricette-secondi 抓取所有数据。

我想将它们放入字典中,如下面的代码所示。 但是,这只是返回一个空列表。

import pprint
detail_recipes = []
for recipe in list_recipes:
  title = ""
  description = ""
  ingredient = ""
  if(len(recipe.find_elements_by_css_selector(".post-title")) > 0):
    title = recipe.find_elements_by_css_selector(".post-title")[0].text
  if(len(recipe.find_elements_by_css_selector(".post-excerpt")) > 0):
    description = recipe.find_elements_by_css_selector(".post-excerpt")[0].text
  if(len(recipe.find_elements_by_css_selector(".nm-ingr")) > 0):
    ingredient = recipe.find_elements_by_css_selector(".nm-ingr")[0].text

  detail_recipes.append({'title': title,
                        'description': description,
                        'ingredient': ingredient
                        })

len(detail_recipes)
pprint.pprint(detail_recipes[0:10])

【问题讨论】:

  • my code解决了您的问题吗?我已经为您提供了有关这些库的更多信息,如果您不熟悉该库,那么这将非常有帮助。如果解决了,请不要忘记将其标记为已接受的答案。如果有任何疑问,请在评论中提问。
  • 谢谢,你的代码很完美。但我无法将数据保存在 CSV 文件中。事实上,当我写: df.to_csv("") 我得到: 'dict' object has no attribute 'to_csv'
  • 你忘了写df=pd.DataFrame(df) df.dropna(axis=0,inplace=True) 两行:)
  • 非常感谢!最后一件事:我还想抓取每个标题的链接。我怎样才能得到它们?
  • 我已经编辑了答案。检查那个。如果你喜欢我的努力,请给我的答案投票。

标签: python selenium web-scraping css-selectors


【解决方案1】:

你可以试试这个:

import requests
import numpy as np
from bs4 import BeautifulSoup as bs
import pandas as pd

url="https://ricetta.it/ricette-secondi"

page=requests.get(url)
soup=bs(page.content,'lxml')

df={'title': [],'description': [],'ingredient':[]}

for div in soup.find_all("div",class_="post-bordered"):
    df["title"].append(div.find(class_="post-title").text)
    try:
        df["description"].append(div.find(class_="post-excerpt").text)
    except:
        df["description"].append(np.nan)
    i=div.find_all(class_="nm-ingr")
    if len(i)>0:
        df["ingredient"].append([j.text for j in i])
    else:
        df["ingredient"].append(np.nan)

df=pd.DataFrame(df)

df.dropna(axis=0,inplace=True)

print(df)

输出:

                               title  ...                                         ingredient
0       Polpette di pane e formaggio  ...  [uovo, pane, pangrattato, parmigiano, latte, s...
1     Torta 7 vasetti alle melanzane  ...  [uovo, olio, latte, yogurt, farina 00, fecola ...
2  Torta a sole con zucchine e speck  ...  [pasta sfoglia, zucchina, ricotta, uovo, speck...
3                    Pesto di limoni  ...  [limone, pinoli, parmigiano, basilico, prezzem...
4                    Bombe di patate  ...  [patata, farina 00, uovo, parmigiano, sale e p...
5             Polpettone di zucchine  ...  [zucchina, uovo, parmigiano, pangrattato, pros...
6                  Insalata di pollo  ...  [petto di pollo, zucchina, pomodorino, insalat...
7                      Club sandwich  ...  [pane, petto di pollo, pomodoro, lattuga, maio...
8                Crostata di verdure  ...  [farina 00, burro, acqua, sale, zucchina, pomo...
9              Pesto di barbabietola  ...  [barbabietola, parmigiano, pinoli, olio, sale,...

[10 rows x 3 columns]

我不知道你是否使用这些库,但该网站不使用 javascript 加载数据,因此我们可以使用 requestsbs4 抓取该网站。如果网站不使用 javascript 加载数据,大多数人更喜欢使用这些库。它比硒更容易和更快。对于显示/显示数据,我使用pandas 也是处理类似数据的表格的首选库。它以类似结构的表格精确打印数据,您还可以将抓取的数据保存在csvexcel file 中。
如果您还想从下一页抓取所有数据,请尝试以下操作:

df={'title': [],'description': [],'ingredient':[]}

for i in range(0,108):
    url=f"https://ricetta.it/ricette-secondi?page={i}"
    page=requests.get(url)
    soup=bs(page.content,'lxml')

    for div in soup.find_all("div",class_="post-bordered"):
        df["title"].append(div.find(class_="post-title").text)
        try:
            df["description"].append(div.find(class_="post-excerpt").text)
        except:
            df["description"].append(np.nan)
        i=div.find_all(class_="nm-ingr")
        if len(i)>0:
            df["ingredient"].append([j.text for j in i])
        else:
            df["ingredient"].append(np.nan)

它将从该网站抓取所有 107 页数据。

您可以使用以下方法将此df 保存到csvexcel file

df.to_csv("<filename.csv>")
# or for excel:
df.to_excel("<filename.xlsx>")

编辑:
当你问你想刮,所有食谱的链接,我已经弄清楚了两件事,首先用-替换标题空间,这是那个食谱的链接,另一个是从那里刮掉的链接,因为你可以使用这段代码:

div.find(class_="post-title")["href"]

它将返回该食谱的链接。对于另一种方法,您可以这样做:

df["links"]=df["title"].apply(lambda x: "https://ricetta.it/"+x.replace(" ","-").lower())
#.lower() is just to not make like a random text but it you remove it also it works.

但我个人建议你只是从网站上抓取链接,因为我们自己的链接可能会出错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多