Python 如何使用BeautifulSoup刮取特定数据

Python 如何使用BeautifulSoup刮取特定数据,python,python-3.x,web-scraping,beautifulsoup,Python,Python 3.x,Web Scraping,Beautifulsoup,我创建了一个脚本来收集这个网站上的一些数据: 我的脚本将出现在所有链接上,如下所示: 并查找前面链接中的所有链接,如以下链接: 我把名字、部门和子部门都删掉了 这是我的剧本: import requests from requests import get from bs4 import BeautifulSoup import pandas as pd import re url = 'https://www.bilansgratuits.fr/' links1 = [] res

我创建了一个脚本来收集这个网站上的一些数据:

我的脚本将出现在所有链接上,如下所示:

并查找前面链接中的所有链接,如以下链接:

我把名字、部门和子部门都删掉了

这是我的剧本:

import requests
from requests import get
from bs4 import BeautifulSoup
import pandas as pd
import re    

url = 'https://www.bilansgratuits.fr/'

links1 = []

results = requests.get(url)    

soup = BeautifulSoup(results.text, "html.parser")

links1 = [a['href']  for a in soup.find("div", {"class": "container_rss blocSecteursActivites"}).find_all('a', href=True)]

secteur = [a.text for a in soup.find("div", {"class": "container_rss blocSecteursActivites"}).find_all('a', href=True)]

links1.pop()
secteur.pop()
    
secteurs = []
soussecteurs = []
names = []
#rankings = []

root_url = 'https://www.bilansgratuits.fr/'
urls1 = [ '{root}{i}'.format(root=root_url, i=i) for i in links1 ]    

for url, secteur in zip(urls1[:1], secteur[:1]):

    results = requests.get(url)

    soup = BeautifulSoup(results.text, "html.parser")

    links = [a['href']  for a in soup.find("div", {"class": "listeEntreprises"}).find_all('a', href=True)]

    soussecteur = [a.text for a in soup.find("div", {"class": "listeEntreprises"}).find_all('a', href=True)]
  
    root_url = 'https://www.bilansgratuits.fr/'
    urls = [ '{root}{i}'.format(root=root_url, i=i) for i in links ]

    for url, soussecteur in zip(urls, soussecteur):

        results = requests.get(url)

        soup = BeautifulSoup(results.text, "html.parser")

        try:
            name = [a.text for a in soup.find("div", {"class": "donnees"}).find_all('a', href=True)]


            for i in name:
                secteurs.append(secteur)

            for i in name:
                soussecteurs.append(soussecteur)
      
        except:
            name = [a.text for a in soup.find("div", {"class": "listeEntreprises"}).find_all('a', href=True)]

            for i in name:
                secteurs.append(secteur)

            for i in name:
                soussecteurs.append(soussecteur)  
          
        names.append(name)  

for i in range(0,len(names)):    
    rx = re.compile(r'^\s+$')

    names[i] = [item.split() for item in names[i] if not rx.match(item)]    

res = []
for list in names:
    for lis in list:
        res.append(' '.join([w for w in lis]))       

data = pd.DataFrame({
    'names' : res,
    'Secteur' : secteurs,
    "Sous-Secteur" : soussecteurs,
    #"Rankings" : rankings
    })


data.to_csv('dftest.csv', sep=';', index=False, encoding = 'utf_8_sig')
我得到如下输出:

但我还想搜集以下信息:

公司名称左边的排名

得到了这样的结果:

当没有排名时,只需在变量中添加“no classement”

但我不知道如何将其添加到我的脚本中


有什么想法吗?

在编写代码时,我稍微整理了一下。诀窍是一步一步地完成每件事

首先,使用
get\u main\u links
从主页上找到您想要的所有链接。 然后我使用
get\u sub\u sectors
查找所有子扇区。此函数有两部分,一部分提取所有
子扇区
,另一部分定位所有排名

排名代码主要基于:

请注意我的代码中的一些额外内容:

  • 除了语句之外,我没有裸露的
    try
    /
    语句,因为这也会捕获
    键盘中断
    和许多其他(有用的)错误,但是如果找不到元素,则会得到AttributeError

  • 我把我所有的数据都放在一个
    目录的
    列表中。这样做的原因是,
    DataFrame
    可以直接处理此表单,以后我不需要指定任何列

  • 我正在使用
    tqdm
    打印进度,因为额外的添加需要更多的时间,并且很高兴看到您的程序实际上正在做一些事情。(
    pip安装tqdm

  • 输出

    names                                              ;Secteur                   ;Sous-Secteur                                                                                                          ;Rankings
    LIMAGRAIN EUROPE (63360)                           ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;1
    LIMAGRAIN (63360)                                  ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;2
    TOP SEMENCE (26160)                                ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;3
    CTRE SEMENCE UNION COOPERATIVE AGRICOLE (37310)    ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;4
    SEMENCES DU SUD (11400)                            ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;5
    KWS MOMONT (59246)                                 ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;6
    TECHNISEM (49160)                                  ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;7
    AGRI-OBTENTIONS (78280)                            ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;8
    LS PRODUCTION (75116)                              ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;9
    SAS VALFRANCE SEMENCES (60300)                     ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;10
    DURANCE HYBRIDES (13610)                           ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;11
    STRUBE FRANCE (60190)                              ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;12
    ID GRAIN (31330)                                   ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;13
    SAGA VEGETAL (33121)                               ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;14
    SOC COOP AGRICOLE VALLEE RHONE VALGRAIN (26740)    ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;15
    ALLIX SARL (33127)                                 ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;16
    PAMPROEUF (79800)                                  ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;17
    PERDIGUIER FOURRAGES (84310)                       ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;18
    PANAM FRANCE (31340)                               ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;19
    HENG SIENG (57260)                                 ;A - Agriculture           ;0111Z - Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses    ;20
    HM.CLAUSE (26800)                                  ;A - Agriculture           ;0113Z - Culture de légumes, de melons, de racines et de tubercules                                ;1
    VILMORIN-MIKADO (49250)                            ;A - Agriculture           ;0113Z - Culture de légumes, de melons, de racines et de tubercules                                ;2
    SARL FERME DE LA MOTTE (41370)                     ;A - Agriculture           ;0113Z - Culture de légumes, de melons, de racines et de tubercules                                ;3
    RIJK ZWAAN FRANCE (30390)                          ;A - Agriculture           ;0113Z - Culture de légumes, de melons, de racines et de tubercules                                ;4
    LE JARDIN DE RABELAIS (37420)                      ;A - Agriculture           ;0113Z - Culture de légumes, de melons, de racines et de tubercules                                ;5
    RENAUD & FILS SARL (17800)                         ;A - Agriculture           ;0113Z - Culture de légumes, de melons, de racines et de tubercules                                ;6
    

    编辑 要将
    无分类
    打印到排名或名称,您可以使用以下方法更改
    \u extract\u sub\u sector\u排名

    
    def _extract_sub_sector_rankings(root, soup: BeautifulSoup):
        data_sub_sectors_rankings = []
    
        try:
            entries = soup.find('div', {'class': 'donnees'}).find_all('tr')
        except AttributeError:
            print(f"\rFailedExtracting: {root}", )
            return [{'rank': 'No classify', 'name': 'No classify'}]
    
        for entry in entries:
            data_sub_sectors_rankings.append({
                'rank': entry.find('td').text,
                'name': entry.find('a').text
            })
        return data_sub_sectors_rankings
    
    之前我使用了
    logging.info
    ,但是默认的日志记录级别是
    warning
    。如果您使用
    logging.warning
    ,您将看到所有失败的链接。他们没有添加
    无分类
    ,而是在原始答案中被跳过


    如果您想给出不同的排名或名称,您可以调整返回值。

    不相关,但有点像:不要在代码中使用太多空格。阅读。对不起,巴杜克,几天前你已经告诉我了,我也读了你的链接,但我认为我没有用太多的空白。我编辑了我的帖子,很抱歉再次感谢你的回答,但我想保持一个与我的结构相当相似的结构:)她速度快(大约3分钟的跑步时间)而且方便。不过还是非常感谢你!!我没有改变你的结构,我在使用你的代码。速度较慢的原因是,您希望获得每个子部分的额外数据,这意味着您现在必须解析每个子部分,这是以前不必做的。在没有排名代码的情况下,我运行这个程序大约需要5秒钟。也许我的第3个注释不清楚。整个程序运行大约需要2-3分钟,但我添加了进度条,这样我就可以看到程序正在运行,因为对于测试,我只需要一点数据。另外,如果progressbar跳转到新的行,你可以使用
    pip install colorama
    ,这应该可以防止跳转。我刚才看到了,但有些页面没有任何排名。你的剧本似乎没有处理这个问题??在dftest中,我没有看到任何“No-classify”。我编辑了答案,为条目提供了
    No-classify
    
    def _extract_sub_sector_rankings(root, soup: BeautifulSoup):
        data_sub_sectors_rankings = []
    
        try:
            entries = soup.find('div', {'class': 'donnees'}).find_all('tr')
        except AttributeError:
            print(f"\rFailedExtracting: {root}", )
            return [{'rank': 'No classify', 'name': 'No classify'}]
    
        for entry in entries:
            data_sub_sectors_rankings.append({
                'rank': entry.find('td').text,
                'name': entry.find('a').text
            })
        return data_sub_sectors_rankings