J'essaie de récupérer les données de Ngo telles que le nom, le numéro de mobile, la ville, etc. de https : //ngodarpan.gov.in/index.php/search/ . Il présente les noms des ONG sous forme de tableau et en cliquant sur chaque nom, une page contextuelle s'ouvre. Dans mon code ci-dessous, j'extrait l'attribut onclick pour chaque ONG, je fais un get suivi d'une demande de post pour extraire les données. J'ai essayé d'y accéder en utilisant du sélénium mais les données json ne viennent pas.
<html> ... ... <body> <div id="container"> <h1>An Error Was Encountered</h1> <p>The action you have requested is not allowed.</p> </div> </body> </html>
En implémentant la partie ci-dessus, nous pouvons obtenir tous les détails du tableau de toutes les pages. Dans ce site, il y a 7721 pages.we peut simplement changer number_of_pages var.
Mais notre objectif est de trouver le numéro de téléphone / email de l'ONG qui est le but principal que nous obtiendrons après avoir cliqué sur le lien du nom de l'ONG.Mais ce n'est pas un href de lien il s'agit plutôt d'une api get req suivie d'une demande de publication pour récupérer data.find dans la section réseau d'inspect
driver.get("https://ngodarpan.gov.in/index.php/search/") # load the web page sleep(2) .... .... driver.find_element(By.NAME,"commit").submit() for page in range(number_of_pages - 1): list_of_rows = [] src = driver.page_source # gets the html source of the page parser = BeautifulSoup(src,'html.parser') sleep(1) table = parser.find("table",{ "class" : "table table-bordered table-striped" }) sleep(1) for row in table.find_all('tr')[:]: list_of_cells = [] for cell in row.find_all('td'): x = requests.get("https://ngodarpan.gov.in/index.php/ajaxcontroller/get_csrf") dat=x.json() z=dat["csrf_token"] print(z) # prints csrf token r= requests.post("https://ngodarpan.gov.in/index.php/ajaxcontroller/show_ngo_info", data = {'id':'','csrf_test_name':'z'}) json_data=r.text # i guess here is something not working it is printing html text but we need text data of post request like mob,email,and here it will print all the data . with open('data1.json', 'a') as outfile: json.dump(json_data, outfile) driver.find_element_by_xpath("//a[contains(text(),'»')]").click()
Il n'y a pas de message d'erreur de ce type, le code est en cours d'exécution mais il imprime du html contenu
list_of_cells = [] for cell in row.find_all('td'): text = cell.text.replace(" ", "") list_of_cells.append(text) list_of_rows.append(list_of_cells) writer=csv.writer(f) writer.writerow(list_of_cells)
3 Réponses :
Passer à une iframe via Selenium et python < / p>
Vous pouvez utiliser un XPath pour localiser:
iframe = driver.find_element_by_xpath ("// iframe [@ name = 'Dialogue Window']")
Passez ensuite à:
driver.switch_to.frame(iframe)
Voici comment revenir au contenu par défaut (hors de):
driver.switch_to.default_content()
Dans votre exemple, je pense que le nom de la "Fenêtre de dialogue" serait CalendarControlIFrame
Une fois que vous êtes passé à ce cadre, vous pourrez utiliser Beautiful Soup pour obtenir le code HTML du cadre.
où puis-je utiliser cette iframe?
devrais-je utiliser ceci là où je fais la demande. obtenir dans mon code
Cela pourrait être fait beaucoup plus rapidement en évitant l'utilisation de Selenium. Leur site semble demander continuellement un jeton avant chaque demande, vous pourriez trouver qu'il est possible de l'ignorer.
Ce qui suit montre comment obtenir le JSON contenant le numéro de mobile et l'adresse e-mail:
['9871249262', 'pnes.delhi@yahoo.com', 'Pragya Network Educational Society', 'S-52559, Narela, DELHI'] ['9810042046', 'mathew.cherian@helpageindia.org', 'HelpAge India', '9270, New Delhi, DELHI'] ['9811897589', 'aipssngo@yahoo.com', 'All India Parivartan Sewa Samiti', 's-43282, New Delhi, DELHI']
Cela vous donnerait le type de sortie suivant pour la première page:
from bs4 import BeautifulSoup import requests import time def get_token(sess): req_csrf = sess.get('https://ngodarpan.gov.in/index.php/ajaxcontroller/get_csrf') return req_csrf.json()['csrf_token'] search_url = "https://ngodarpan.gov.in/index.php/ajaxcontroller/search_index_new/{}" details_url = "https://ngodarpan.gov.in/index.php/ajaxcontroller/show_ngo_info" sess = requests.Session() for page in range(0, 10000, 10): # Advance 10 at a time print(f"Getting results from {page}") for retry in range(1, 10): data = { 'state_search' : 7, 'district_search' : '', 'sector_search' : 'null', 'ngo_type_search' : 'null', 'ngo_name_search' : '', 'unique_id_search' : '', 'view_type' : 'detail_view', 'csrf_test_name' : get_token(sess), } req_search = sess.post(search_url.format(page), data=data, headers={'X-Requested-With' : 'XMLHttpRequest'}) soup = BeautifulSoup(req_search.content, "html.parser") table = soup.find('table', id='example') if table: for tr in table.find_all('tr'): row = [td.text for td in tr.find_all('td')] link = tr.find('a', onclick=True) if link: link_number = link['onclick'].strip("show_ngif(')") req_details = sess.post(details_url, headers={'X-Requested-With' : 'XMLHttpRequest'}, data={'id' : link_number, 'csrf_test_name' : get_token(sess)}) json = req_details.json() details = json['infor']['0'] print([details['Mobile'], details['Email'], row[1], row[2]]) break else: print(f'No data returned - retry {retry}') time.sleep(3)
Pour l'itération sur toutes les pages, il affiche une erreur pour tr dans table.find_all ('tr') [:]: AttributeError: l'objet 'NoneType' n'a pas d'attribut 'find_all'
J'ai remarqué que le site ne renvoie parfois pas la bonne page, il se peut que la limitation de débit soit activée. Vous devrez peut-être tester table
pour Aucun
et réessayer avec un délai.
Le code n'itère pas toutes les pages, il n'imprime que la première page
Si votre code fonctionne correctement, veuillez m'envoyer mon courrier électronique, ce serait d'une grande aide monsieur
Correct, il n'a été conçu que pour vous montrer comment obtenir la première page. Vous devrez ajouter une autre boucle pour parcourir toutes les pages.
akashrao96@gmail.com
Monsieur, j'ai ajouté une autre boucle
J'ai publié le code mis à jour dans la section des réponses ci-dessous
J'ai ajouté dans la section ci-dessous s'il vous plaît chercher une fois.Ces données sont très imp pour moi.Je travaille dessus pendant plusieurs jours mais je ne peux pas les gratter jusqu'à présent
Mon code mis à jour fonctionne maintenant pour plusieurs pages. Le jeton devait être obtenu pour chaque boucle.
Monsieur, il n'itère pas il renvoie Aucune donnée renvoyée après l'extraction de la première page
Veuillez vous assurer que vous avez copié la dernière version (actualisez la page), cela devrait fonctionner correctement.
Vous pouvez le voir fonctionner ici: lancer la démo Appuyez simplement sur Exécuter
Je l'ai eu Très Merci à vous monsieur de m'aider
J'essaie de vider les données json dans un fichier, il affiche une erreur
Il suffit généralement de poser une question à la fois. Je vous suggère d'accepter cette réponse (cliquez sur la coche) puis de commencer une nouvelle question concernant votre problème JSON.
Je suis en train de parcourir toutes les pages et d'extraire les données en une seule tentative Après avoir extrait les données d'une page, il n'itère pas d'autres pages
.... .... ['9829059202', 'cecoedecon@gmail.com', 'CECOEDECON', '206, Jaipur, RAJASTHAN'] ['9443382475', 'odamindia@gmail.com', 'ODAM', '43/1995, TIRUCHULI, TAMIL NADU'] ['9816510096', 'shrisaisnr@gmail.com', 'OPEN EDUCATIONAL DEVELOPMENT RESEARCH AND WELFARE', '126/2004, SUNDERNAGAR, HIMACHAL PRADESH'] ['9425013029', 'card_vivek@yahoo.com', 'Centre for Advanced Research and Development', '25634, Bhopal, MADHYA PRADESH'] ['9204645161', 'secretary_smvm@yahoo.co.in', 'Srijan Mahila Vikas Manch', '833, Chakradharpur, JHARKHAND'] ['9419107550', 'amarjit.randwal@gmail.com', 'J and K Sai Star Society', '4680-S, Jammu, JAMMU & KASHMIR'] No data returned - retry 2 No data returned - retry 2 No data returned - retry 2 No data returned - retry 2 No data returned - retry 2 ... ...
Pourriez-vous modifier votre question pour afficher un exemple de recherche et le début des résultats que vous essayez d'extraire.
Mon principal motif est d'extraire le numéro de téléphone mobile ou l'identifiant de messagerie qui apparaît après avoir cliqué sur le nom de l'ONG.
Votre token est passé sous forme de chaîne
z
et non de variable, essayezata = {'id': '', 'csrf_test_name': z}
. Vous devrez également transmettre unid
approprié