I have written this code for crawling and scraping search results from Google. But it's super slow when I run it.
What it does: read a pandas column, search values in Google and take the first result link then extract the siret number in link Ex.
https://www.infogreffe.fr/entreprise-societe/380760702-entreprise-de-decoration-et-d-innovation-sarl-340591B001420000.html the siret is 380760702. In every iteration I save this number in
found_results
.
To do that, there are three functions:
rechercher_google()
to get the htmlparse_results()
to parse the url where the digit isrecherche_google()
to wrap to these two functions above.
Could it be less greedy in complexity or be better?
# Function pour recupere la html
USER_AGENT = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}
def rechercher_google(search_term, number_results, language_code):
'''
input: Nom de l'entreprise à siretiser, le nombre de page et la langue
output: La page resultat dde google en html stocker au format raw html
'''
assert isinstance(search_term, str), 'Il doit etre en string'
assert isinstance(number_results, int), 'DOit etre en chiffre'
escaped_search_term = search_term.replace(' ', '+')
g_url = 'https://www.google.fr/search?q={}&num={}&hl={}'.format(escaped_search_term, number_results, language_code)
response = requests.get(g_url, headers = USER_AGENT)
response.raise_for_status()
return response.text, search_term
# function pour recuperer ce qu'on a besoin dans la page
def parse_results(html, keyword):
'''
Input: la sortie de la fortion fetch_results()
output: le nom de l'entreprise et le siret
'''
soup = bs(html, 'html.parser')
found_results = []
rank = 1
result_block = soup.find_all('div', attrs={'class': 'g'}) # g indique q'on est bien dans un resultat normal
for result in result_block:
link = result.find('a', href=True)
title = result.find('h3')
if link and title:
link = link['href']
title = title.get_text()
if link != '#':
try:
found_results.append({'siret':link.split('/')[4].split('-')[0]})
except Exception as list_error:
print('error in fund_results {}'.format(list_error))
rank += 1
return found_results
# wrap up, le tout dans un global function qui appelle les deux premiere.
def scrape_google(search_term, number_results, language_code):
'''
input: il mange les deux premier functions
output: une liste de dict des nom d'entreprise avec leur siret et club
'''
try:
html, keyword = rechercher_google(search_term, number_results, language_code)
results = parse_results(html, keyword)
return results
except AssertionError:
raise Exception("Probleme d'argument")
except requests.HTTPError:
raise Exception(" :/ Google a bloqué le ip")
except requests.RequestException:
raise Exception(" :/ Probleme de connexion/proxy")
To run it
# Siret à partir de google
start_time = time.time()
data = []
for keyword in liste_partenaire.Partenaire:
keyword = keyword+ ' ' + 'infogreffe Montpellier'
name.append(keyword)
try:
results = scrape_google(keyword, 1, "fr")
for result in results:
data.append(results[0]['siret'])
except Exception as e:
print(' :( Error in results:: [ {} ]'. format(e))
finally:
time.sleep(11)
print("--- %s seconds d'éxecution ---" % (time.time() - start_time)) # 48 minutes
# save
time.sleep(11)
?! \$\endgroup\$