高效的web抓取Python
嗨,我是一个新的网站刮,并想刮一个网站与beautifulsoop。现在我想知道 关于如何编写高效的代码。这是一个关于自行车的网站,他们有几辆自行车,每辆都有价格、状态、距离和持续时间的功能。他们都有相同的等级“产品专长”。将所有这些特性放入数据帧的最有效方法是什么?我特别提出这个问题,因为所有特性都具有相同的类,循环在我看来效率很低高效的web抓取Python,python,html,pandas,web-scraping,beautifulsoup,Python,Html,Pandas,Web Scraping,Beautifulsoup,嗨,我是一个新的网站刮,并想刮一个网站与beautifulsoop。现在我想知道 关于如何编写高效的代码。这是一个关于自行车的网站,他们有几辆自行车,每辆都有价格、状态、距离和持续时间的功能。他们都有相同的等级“产品专长”。将所有这些特性放入数据帧的最有效方法是什么?我特别提出这个问题,因为所有特性都具有相同的类,循环在我看来效率很低 <div class="product-smalltext"> <p class="product-feat&qu
<div class="product-smalltext">
<p class="product-feat">
<span>GBP 6'900 <small>(changeable)</small></span><br/> price
</p>
<p class="product-feat">
<span>new</span><br/> state
</p>
<p class="product-feat">
<span>10'000 km</span><br/> distance
</p>
<p class="product-feat">
<span>48 months</span><br/> duration
</p>
您可以使用列表理解并直接构造数据帧:
pd.DataFrame([[y.text
for y in x.select('p.product-feat > span')]
for x in soup.select('div[class="product-smalltext"]')],
columns=['price', 'state', 'distance', 'duration'])
pd.DataFrame([{y.find('br').next_sibling.strip(): y.find('span').text
for y in x.select('p.product-feat')}
for x in soup.select('div[class="product-smalltext"]')])
输出(我又添加了一个
,以确保它可以处理每页多个项目):
更新:我们还可以从文本中提取产品功能的名称,并将其用作列名。如果缺少一些值,我们将在数据帧中获得
NaN
s:
pd.DataFrame([[y.text
for y in x.select('p.product-feat > span')]
for x in soup.select('div[class="product-smalltext"]')],
columns=['price', 'state', 'distance', 'duration'])
pd.DataFrame([{y.find('br').next_sibling.strip(): y.find('span').text
for y in x.select('p.product-feat')}
for x in soup.select('div[class="product-smalltext"]')])
使用特定网站更新2::
resp = requests.get('https://www.leasingmarkt.ch/listing')
soup = bs4.BeautifulSoup(resp.text)
df = pd.DataFrame([{y.find('br').next_sibling.strip(): y.find('span').text
for y in x.select('p.product-feat')}
for x in soup.select('div[class="product-smalltext"]')])
df
输出:
Anzahlung Erstzulassung Jährliche Fahrleistung \
0 CHF 0 (anpassbar) Neuwagen 10'000 km (anpassbar)
1 CHF 13'250 (anpassbar) Neuwagen 10'000 km (anpassbar)
2 CHF 2'000 (anpassbar) Neuwagen 10'000 km
3 CHF 10'000 (anpassbar) Neuwagen 15'000 km (anpassbar)
4 CHF 1'500 (anpassbar) Neuwagen 10'000 km
5 CHF 3'500 (anpassbar) Neuwagen 10'000 km
6 CHF 6'900 (anpassbar) Neuwagen 10'000 km
7 CHF 10'500 (anpassbar) Neuwagen 10'000 km (anpassbar)
8 CHF 0 (anpassbar) 08/2015 10'000 km
9 CHF 0 (anpassbar) Neuwagen 10'000 km (anpassbar)
Laufzeit Kilometerstand Leistung
0 48 Monate (anpassbar) 0 km 204 PS (150 kW), Elektro
1 48 Monate (anpassbar) 0 km 245 PS (180 kW), Benzin
2 48 Monate 0 km 190 PS (140 kW), Benzin
3 48 Monate (anpassbar) 0 km 150 PS (110 kW), Benzin
4 48 Monate 0 km 204 PS (150 kW), Elektro
5 48 Monate 0 km 320 PS (235 kW), Benzin
6 48 Monate 0 km 129 PS (95 kW), Benzin
7 48 Monate (anpassbar) 0 km 184 PS (135 kW), Benzin
8 48 Monate 46'000 km 190 PS (140 kW), Diesel
9 48 Monate (anpassbar) 0 km 320 PS (235 kW), Benzin
更新3:下面是关于
selenium
:
url = 'https://www.leasingmarkt.ch/listing'
driver = webdriver.Chrome()
driver.get(url)
html = driver.page_source
soup = bs4.BeautifulSoup(html)
df = pd.DataFrame([{y.find('br').next_sibling.strip(): y.find('span').text
for y in x.select('p.product-feat')}
for x in soup.select('div[class="product-smalltext"]')])
您可以使用列表理解并直接构造数据帧:
pd.DataFrame([[y.text
for y in x.select('p.product-feat > span')]
for x in soup.select('div[class="product-smalltext"]')],
columns=['price', 'state', 'distance', 'duration'])
pd.DataFrame([{y.find('br').next_sibling.strip(): y.find('span').text
for y in x.select('p.product-feat')}
for x in soup.select('div[class="product-smalltext"]')])
输出(我又添加了一个
,以确保它可以处理每页多个项目):
更新:我们还可以从文本中提取产品功能的名称,并将其用作列名。如果缺少一些值,我们将在数据帧中获得
NaN
s:
pd.DataFrame([[y.text
for y in x.select('p.product-feat > span')]
for x in soup.select('div[class="product-smalltext"]')],
columns=['price', 'state', 'distance', 'duration'])
pd.DataFrame([{y.find('br').next_sibling.strip(): y.find('span').text
for y in x.select('p.product-feat')}
for x in soup.select('div[class="product-smalltext"]')])
使用特定网站更新2::
resp = requests.get('https://www.leasingmarkt.ch/listing')
soup = bs4.BeautifulSoup(resp.text)
df = pd.DataFrame([{y.find('br').next_sibling.strip(): y.find('span').text
for y in x.select('p.product-feat')}
for x in soup.select('div[class="product-smalltext"]')])
df
输出:
Anzahlung Erstzulassung Jährliche Fahrleistung \
0 CHF 0 (anpassbar) Neuwagen 10'000 km (anpassbar)
1 CHF 13'250 (anpassbar) Neuwagen 10'000 km (anpassbar)
2 CHF 2'000 (anpassbar) Neuwagen 10'000 km
3 CHF 10'000 (anpassbar) Neuwagen 15'000 km (anpassbar)
4 CHF 1'500 (anpassbar) Neuwagen 10'000 km
5 CHF 3'500 (anpassbar) Neuwagen 10'000 km
6 CHF 6'900 (anpassbar) Neuwagen 10'000 km
7 CHF 10'500 (anpassbar) Neuwagen 10'000 km (anpassbar)
8 CHF 0 (anpassbar) 08/2015 10'000 km
9 CHF 0 (anpassbar) Neuwagen 10'000 km (anpassbar)
Laufzeit Kilometerstand Leistung
0 48 Monate (anpassbar) 0 km 204 PS (150 kW), Elektro
1 48 Monate (anpassbar) 0 km 245 PS (180 kW), Benzin
2 48 Monate 0 km 190 PS (140 kW), Benzin
3 48 Monate (anpassbar) 0 km 150 PS (110 kW), Benzin
4 48 Monate 0 km 204 PS (150 kW), Elektro
5 48 Monate 0 km 320 PS (235 kW), Benzin
6 48 Monate 0 km 129 PS (95 kW), Benzin
7 48 Monate (anpassbar) 0 km 184 PS (135 kW), Benzin
8 48 Monate 46'000 km 190 PS (140 kW), Diesel
9 48 Monate (anpassbar) 0 km 320 PS (235 kW), Benzin
更新3:下面是关于
selenium
:
url = 'https://www.leasingmarkt.ch/listing'
driver = webdriver.Chrome()
driver.get(url)
html = driver.page_source
soup = bs4.BeautifulSoup(html)
df = pd.DataFrame([{y.find('br').next_sibling.strip(): y.find('span').text
for y in x.select('p.product-feat')}
for x in soup.select('div[class="product-smalltext"]')])
谢谢。我刚刚意识到,如果某些行的状态为空,您会怎么做?如何在数据帧中使其成为nan,以及如何避免所有值向左移动?@corianne1234请查看更新。这很好,谢谢。剩下的唯一一件事是,这不起作用,因为还有类“product smalltext listing”,所以soup.select('div.product-smalltext')])将同时提供product smalltext listing和product smalltext,并且只有product smalltext具有product feat。这在循环解决方案中起作用,但在这里您将如何执行?很酷,因此您希望将其指定为只有“product smalltext”类。您可以使用
…为汤中的x执行此操作。选择('div[class=“product smalltext”]”)]…
,请查看更新的带有selenium的更新3(对我来说效果很好,与更新2中的输出相同),非常感谢。我刚刚意识到,如果某些行的状态为空,您会怎么做?如何在数据帧中使其成为nan,以及如何避免所有值向左移动?@corianne1234请查看更新。这很好,谢谢。剩下的唯一一件事是,这不起作用,因为还有类“product smalltext listing”,所以soup.select('div.product-smalltext')])将同时提供product smalltext listing和product smalltext,并且只有product smalltext具有product feat。这在循环解决方案中起作用,但在这里您将如何执行?很酷,因此您希望将其指定为只有“product smalltext”类。您可以使用…为汤中的x执行此操作。选择('div[class=“product smalltext”]”)]…
,请查看更新的带有selenium的更新3(对我来说效果很好,与更新2中的输出相同)