网页抓取返回空字典

时间:2021-07-25 20:53:52

标签: python selenium web-scraping css-selectors

我正在尝试使用 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])

1 个答案:

答案 0 :(得分:2)

你可以试试这个:

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.

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