3
votes

Demander plusieurs URL dans le script de scraping Python

Je crée un web-scraper et j'essaye de demander plusieurs URL qui partagent le même chemin d'URL, à l'exception d'un identifiant numéroté.

Mon code pour gratter une URL est le suivant:

import requests
from bs4 import BeautifulSoup as bs

pages = []

for i in range(11003058, 11003059, 00930291):
```url = 'https://beta.companieshouse.gov.uk/company/' + str(i) + '/officers'
```pages.append(url)

for item in pages:
```page = requests.get(item)
```soup = bs(page.text, 'lxml')

names = [item.text.strip() for item in soup.select('[class^=appointment]:not(.appointments-list):has([id^="officer-role-"]:contains(Director)) h2')]

print(names)

L'URL partage la même structure à l'exception des numéros de société. J'ai essayé le code suivant pour essayer de le faire gratter plusieurs pages, mais sans succès:

import requests
from bs4 import BeautifulSoup as bs

r = requests.get('https://beta.companieshouse.gov.uk/company/00930291/officers')
soup = bs(r.content, 'lxml')
names = [item.text.strip() for item in soup.select('[class^=appointment]:not(.appointments-list):has([id^="officer-role-"]:contains(Director)) h2')]
print(names)

Cela ne me donne que la première page (/ 11003058 / officiers) , pourquoi ne les parcourt-il pas? Quelqu'un peut-il aider?


0 commentaires

3 Réponses :


1
votes

Cela devrait résoudre vos problèmes:

La fonction range () renvoie une séquence de nombres, commençant par défaut à 0, et s'incrémente de 1 (par défaut) et se termine à un nombre spécifié.

Syntaxe:

['MASRAT, Suheel', 'MARSHALL, Jack', 'SUTTON, Tim', 'COOMBES, John Frederick', 'BROWN, Alistair Stuart', 'COOMBES, Kenneth', 'LAFONT, Jean-Jacques Mathieu', 'THOMAS-KEEPING, Lindsay Charles', 'WILLIAMS, Janet Elizabeth', 'WILLIAMS, Roderick', 'WRAGG, Barry']

https://docs.python.org/3/library/functions.html#func-range p>

Remplacez votre code par:

names = []
for items in soup:
    h2Obj = items.select('[class^=appointment]:not(.appointments-list):has([id^="officer-role-"]:contains(Director)) h2')
    for i in h2Obj:
        tagArray = i.findChildren()
        for tag in tagArray:
            if isinstance(tag,Tag) and tag.name in 'a':
                names.append(tag.text)

Vous devez initialiser soupe en tant que liste avant d'itérer les pages:

soupe = []

Et ajouter dans la liste de soupe:

for item in pages:
  page = requests.get(item)
  soup.append(bs(page.text, 'lxml'))

afficher la liste des noms:

company_id = ["11003058","11003059","00930291"]

for i in company_id:
    url = 'https://beta.companieshouse.gov.uk/company/' + str(i) + '/officers'
    pages.append(url)

O / P :

 range(start, stop, step)

Ajouter le haut du script:

à partir de la balise d'importation bs4.element


5 commentaires

Merci pour ton aide. Cela fonctionne, mais ne montre que les URL dont il provient. Comment puis-je incorporer la section names =, afin qu'elle imprime les noms plutôt que l'url des pages?


names = [item.text.strip () for item in soup.select ('[class ^ = nomination]: not (.appointments-list): ha‌ s ([id ^ = "officer-role‌ -"]: contient (Directo‌ r)) h2 ')]


J'ai ajouté les noms = ... juste après le soup.append ... sur une nouvelle ligne et ajouté print (noms), mais cela génère cette erreur: AttributeError: l'objet 'list' n'a pas d'attribut 'select' . Qu'est-ce que je fais mal :-(


car les noms ont un type d'instance de liste, vous devez effectuer une nouvelle itération


Vous êtes une star absolue !! Cela fonctionne parfaitement, merci beaucoup :-)



0
votes

La syntaxe de range est range (start, stop, step) . Il effectue une boucle de start à stop - 1 et augmente à chaque fois de step . Vous faites quelque chose de bizarre ici car dans votre cas, stop équivaut à start + 1 donc il ne va boucler qu'une seule fois, avec la valeur start .

Je suppose que vous voulez juste obtenir ces 3 URL:

for i in (11003058, 11003059, 00930291):


0 commentaires

0
votes

Plage en boucles: la boucle inclut toujours start_value et exclut end_value pendant l'itération

Essayez ceci:

import requests
from bs4 import BeautifulSoup as bs

pages = ['11003058', '11003059', '00930291']
i=0
while i<len(pages):
  url = 'https://beta.companieshouse.gov.uk/company/' + pages(i) + '/officers'
  pages.append(url)
  i+1

for item in pages:
  page = requests.get(item)
  soup = bs(page.text, 'lxml')

names = [item.text.strip() for item in soup.select('[class^=appointment]:not(.appointments-list):has([id^="officer-role-"]:contains(Director)) h2')]

print(names)


2 commentaires

Merci pour l'aide. J'ai essayé votre code, mais il génère l'erreur: Fichier "444.py", ligne 6, dans tandis que i


oh, désolé, j'ai oublié de définir «i», maintenant vous pouvez l'exécuter.