我是python的新手。昨天刚开始。我想从该网站https://www.letudiant.fr/educpros/responsables-enseignement-superieur/critere-Responsable.html抓取信息。我想提取联系人的基本信息,例如全名,职位,电话,电子邮件,公司。
这是我用Beautifulsoup和Requests编写的代码:
import requests
from bs4 import BeautifulSoup
for page in range(1, 1000): # Number of pages plus one
url = "https://www.letudiant.fr/educpros/responsables-enseignement-superieur/critere-directeur.html".format(page)
r = requests.get(url, headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36'})
soup = BeautifulSoup(r.text, 'lxml')
for contenu in soup.find_all('div', class_='box-content2'):
for link in contenu.find_all('a'):
page = "https://www.letudiant"
data = page + link.get('href')
contact = requests.get(data)
soup_bis = BeautifulSoup(contact.text, 'lmxl')
for full_name in soup_bis.find_all('box-content2'):
print(full_name)
答案 0 :(得分:0)
一些指针:
1)您正在将page
从数字循环变量更改为循环内的字符串url值。将内部变量更改为其他名称,例如base
,并记得最后添加.fr
。然后,您只需使用以下方式即可获取所有内部链接:
base = "https://www.letudiant.fr"
# other code
links = [base + item['href'] for item in soup.select('.box-content2 a')]
2)您正在使用.format(page)
,但URL字符串中没有占位符。您想要:
url = "https://www.letudiant.fr/educpros/responsables-enseignement-superieur/critere-directeur/page-{}.html".format(page)
3)考虑到您正在提出的请求数量,例如考虑requests.Session()
4)有些链接已被删除,因此请考虑从网址级别页面(而不是链接级别)获取名称,职位和公司(乍一看似乎是填充的)。
这还没有经过充分测试,但是结构可能像这样:
import requests
from bs4 import BeautifulSoup
base = "https://www.letudiant.fr"
results = []
with requests.Session() as s:
for page in range(1, 2):
url = "https://www.letudiant.fr/educpros/responsables-enseignement-superieur/critere-directeur/page-{}.html".format(page)
headers = {'User-Agent': 'Mozilla/5', 'Referer' : url}
r = s.get(url, headers = headers)
soup = BeautifulSoup(r.text, 'lxml')
links = [base + item['href'] for item in soup.select('.box-content2 a')]
temp_names = [item.text.strip() for item in soup.select('.box-content2 h3')]
temp_positions = [item.text.strip() for item in soup.select('.box-content2 h4')]
temp_companies = [re.sub('\s{2,}', ' ',' '.join(item.text.split('\n'))) for item in soup.select('.box-content2 .p1')]
i = 0
for link in links:
r = s.get(link)
soup = BeautifulSoup(r.text, 'lxml')
try:
data = soup.select_one('.box-content2')
name = getattr(data.find('h3'), 'text', 'N/A').strip()
position_company = getattr(data.find('h4'), 'text', 'N/A').strip()
if position_company:
position = position_company.split('\n')[0].strip()
company = position_company.split('\n')[2].strip()
address = re.sub('\s{2,}', ' ', ' '.join(getattr(data.find('p'), 'text', 'N/A').split('\n')).strip())
tel = data.select_one('[href^=tel]').text.strip() if data.select_one('[href^=tel]') else 'N/A'
# email - not scrapable
row = [name, position, company, address, tel]
except:
row = [temp_names[i], temp_positions[i], temp_companies[i], 'N/A', 'N/A']
results.append(row)
i+=1
答案 1 :(得分:0)
您可以使用while
循环继续抓取,直到不再显示页面为止:
from bs4 import BeautifulSoup as soup
import requests, re
def get_person(_d):
new_d = soup(requests.get(f"https://www.letudiant.fr{_d.find('a')['href']}").text, 'html.parser')
b = new_d.find('div', {'class':'box-content2'})
return 'N/A' if not b else {'name':getattr(b.find('h3'), 'text', 'N/A'), 'position':b.find('h4').contents[0], 'company':b.find('h4').contents[-2].text, 'tel':getattr(new_d.find('a', {'href':re.compile('tel:\d+$')}), 'text', 'N/A')}
count, results = 1, []
d = soup(requests.get(f'https://www.letudiant.fr/educpros/responsables-enseignement-superieur/critere-Responsable/page-{count}.html').text, 'html.parser')
while any(str(count+1) in i['href'] for i in d.find_all('a', {'href':re.compile('page-\d+\.html$')})):
results.append([get_person(i) for i in d.find_all('div', {'class':'box2 with-border theme-annuaire'})])
d = soup(requests.get(f'https://www.letudiant.fr/educpros/responsables-enseignement-superieur/critere-Responsable/page-{count+1}.html').text, 'html.parser')
count += 1
results.append([get_person(i) for i in d.find_all('div', {'class':'box2 with-border theme-annuaire'})])
clean_data = [[c if isinstance(c, str) else [{a:re.sub('^[\r\n\s]+|[\n\s]+$', '', b) for a, b in c.items()}] for c in i] for i in results]
输出(由于SO的字符限制,前两页):
[[[{'name': 'Aknin Nathalie', 'position': 'Responsable des relations internationales -', 'company': 'ENSA Nantes', 'tel': '02.40.16.02.41'}], [{'name': 'Ellenberger Eva', 'position': 'Responsable des relations internationales -', 'company': "Spéos l'école photo internationale Paris", 'tel': '01.40.09.18.58'}], [{'name': 'Claeys Jean-Luc', 'position': 'Responsable des classes préparatoires -', 'company': 'Lycée Saint-Rémi Roubaix', 'tel': '03.20.89.41.41'}], [{'name': 'Gadelii Karl', 'position': 'Responsable Erasmus (études nordiques) -', 'company': "UFR d'études germaniques et nordiques - faculté des lettres Paris (Sorbonne université)", 'tel': 'N/A'}], [{'name': 'Poulain Florence', 'position': 'Responsable de la communication -', 'company': 'ITII Bourgogne Auxerre (Dijon)', 'tel': '03.86.49.26.18'}], [{'name': 'Delapierre Anne', 'position': 'Responsable pédagogique -', 'company': 'ES2C Limoges', 'tel': '05.55.38.48.58'}], [{'name': 'Bondon Thierry', 'position': 'Responsable des classes préparatoires -', 'company': 'Lycée international de Valbonne', 'tel': '04.92.96.55.33'}], [{'name': 'Harrell Danielle', 'position': 'Responsable des relations internationales -', 'company': 'ArtFx Montpellier', 'tel': '04.99.77.01.42'}], [{'name': 'Doret Julie', 'position': 'Responsable de la communication -', 'company': 'Ionis-STM Ivry-sur-Seine', 'tel': '01.53.14.59.35'}], [{'name': 'Moreno Julie', 'position': 'Responsable de la communication -', 'company': 'Institut des éducateurs Paris', 'tel': '09.86.51.38.24'}], [{'name': 'Duris Marie-Françoise', 'position': 'Responsable des relations entreprises -', 'company': 'Lycée Notre-Dame Castres', 'tel': '05.63.62.58.00'}], [{'name': 'Torrente Pierre', 'position': 'Directeur adjoint, responsable du site de Foix -', 'company': 'ISTHIA Foix (Toulouse Jean-Jaurès)', 'tel': '05.61.02.19.74'}], [{'name': 'Vasseur Claudine', 'position': 'Responsable des relations extérieures -', 'company': 'Lycée Sophie-Berthelot Calais', 'tel': '03.21.19.77.77'}], [{'name': 'Lamkhioued Bouchaïb', 'position': 'Responsable des relations internationales -', 'company': 'UFR de pharmacie (Reims)', 'tel': '03.26.91.81.45'}], 'N/A', [{'name': 'Zouhdi Saïd', 'position': 'Responsable des relations internationales -', 'company': 'Polytech Paris-Sud Orsay (Paris-Sud)', 'tel': '01.69.33.86.00'}], [{'name': 'Sourlier Patricia', 'position': 'Responsable des relations internationales -', 'company': 'ITII PACA Istres', 'tel': '04.42.11.44.68'}], [{'name': 'Guyot Nicolas', 'position': "Responsable de l'alternance -", 'company': 'MFR Beaupréau-en-Mauges', 'tel': '02.41.63.02.04'}], [{'name': 'Grandidier Jean-Claude', 'position': 'Responsable de la recherche -', 'company': 'ISAE-ENSMA Chasseneuil-du-Poitou', 'tel': '05.49.49.83.41'}], [{'name': 'Onde Jean-Claude', 'position': 'Responsable des BTS -', 'company': 'Lycée Félix-Esclangon Manosque', 'tel': '04.92.70.54.70'}]], [[{'name': 'Chancerelle Marie-Alix', 'position': 'Responsable des relations entreprises -', 'company': 'IPAG Business School, campus de Paris', 'tel': '01.53.63.36.30'}], [{'name': 'Junek Françoise', 'position': 'Responsable de la communication -', 'company': 'IUT Valence (Grenoble Alpes)', 'tel': '04.75.41.88.69'}], [{'name': "Prud'homme Brigitte", 'position': 'Responsable pédagogique -', 'company': 'IFMEM Reims', 'tel': '03.26.78.74.67'}], [{'name': 'Canti Aldo', 'position': 'Responsable pédagogique -', 'company': 'CREPS Saint-Raphaël', 'tel': '04.94.40.27.40'}], [{'name': 'Cueille Arnaud', 'position': 'Responsable pédagogique -', 'company': 'EPSI Bordeaux', 'tel': '05.56.43.13.13'}], [{'name': 'Beaud Stéphane', 'position': 'Responsable des BTS -', 'company': 'Lycée Saint-Michel Annecy', 'tel': '04.50.45.05.20'}], [{'name': 'Faveret Laurence', 'position': 'Responsable pédagogique -', 'company': 'IRFSS CRF Besançon', 'tel': '03.81.83.19.17'}], [{'name': 'de Chantal François', 'position': 'Responsable de la communication (masters) -', 'company': 'UFR études anglophones (Paris 7)', 'tel': '01.57.27.58.00'}], [{'name': 'Loyer Sébastien', 'position': 'Responsable de la communication -', 'company': 'Lycée Saint-Paul Vannes', 'tel': '02.97.46.61.37'}], [{'name': 'Baran Oliwia', 'position': 'Responsable de la communication -', 'company': 'ESPOL (Université catholique de Lille)', 'tel': '03.59.56.79.76'}], [{'name': 'Lebret Thierry', 'position': 'Responsable des relations internationales -', 'company': 'UFR des sciences de la santé Simone Veil Montigny-le-Bretonneux (Versailles)', 'tel': '01.70.42.95.15'}], [{'name': 'Cazals Nicolas', 'position': 'Responsable des relations entreprises -', 'company': "Institut supérieur de l'environnement Versailles", 'tel': '01.30.68.09.10'}], [{'name': 'Rochery Laurence', 'position': 'Responsable des relations entreprises -', 'company': 'ESCEM école de management, campus de Tours', 'tel': '02.47.22.41.78'}], [{'name': 'Gautier Eric', 'position': 'Responsable des relations internationales -', 'company': 'UFR études arabes et hébraïques - faculté des lettres Paris (Sorbonne université)', 'tel': '01.40.46.25.15'}], [{'name': 'Boutroy Peggy', 'position': 'Responsable des relations internationales -', 'company': 'Lycée Baudimont-Saint-Charles Arras', 'tel': '03.21.16.18.00'}], [{'name': 'Gomme Isabelle', 'position': 'Responsable des relations entreprises -', 'company': 'Polytech Paris-Sud Orsay (Paris-Sud)', 'tel': '01.69.33.86.00'}], [{'name': 'Colas Jean-Marie', 'position': 'Responsable de la communication -', 'company': 'Supcréa Grenoble', 'tel': '04.76.87.74.75'}], [{'name': 'Aubrun Philippe', 'position': 'Responsable des relations entreprises -', 'company': 'Lycée Duplessis-Mornay Saumur', 'tel': '02.41.53.05.30'}], 'N/A', [{'name': 'Maunier Michel', 'position': 'Responsable de la communication -', 'company': 'ENSA Nice', 'tel': '04.92.07.73.91'}]]]
>>>len(clean_data)
50