我正在做一些网站爬网练习。我想获得欧洲的汽车销售数据,然后再准备一些地块。 因此,我发现http://carsalesbase.com/european-car-sales-data/是一个很好的数据源。 我设法获得了某个特定制造商的一种特定车辆的销售数据。如果修改URL,我还可以访问多辆汽车以及可能有多家制造商的销售编号。
这是我的代码:
sortedReplies:computed('model.ticket.replies[]',function(){
return this.get('model.ticket.replies').sortBy('created_at:desc');
})
例如我可以访问三辆福特汽车的销售数据。
但是,我想遍历每个制造商的每辆车。 为此,Carsalesbase有两个下拉菜单。 一种是给制造商的。我已经设法从该菜单中读取所有可能的值。 这是一个“值/文本”对:
import requests
from bs4 import BeautifulSoup as bs
import numpy as np
import matplotlib.pyplot as plt
car_type=0
car_spec=['ford-focus','ford-fiesta','ford-ecosport']
my_url='http://carsalesbase.com/european-car-sales-
data/ford/'+car_spec[car_type]+'/'
page = requests.get(my_url)
soup = bs(page.content, 'html.parser')
t=soup.find("table")
rows=t.find_all('td')
第二个下拉列表用于汽车本身。只要在第一个菜单中未选择汽车品牌,此选项仅包含默认值。在第一个下拉列表中选择制造商后,第二个将填充该制造商的所有汽车。 我要做的是以编程方式填充第一个下拉菜单,以便我可以读出第二个菜单。
之后,我相信我可以使用以下http-方案访问所有销售数据:
http://carsalesbase.com/?hide-value=1&brand-option=17&model-option=2089&css-go=Go
我使用“网络”标签中的chrome-developers工具观察到了这一点。请注意,“ brand-option = 17”对应于Alfa Romeo,与我的手动输入匹配。
我想我缺少的链接就是如何以编程方式填充下拉菜单。
任何人都可以帮忙吗?
ps:我读到有关Selenium的信息,这似乎是一个合适的工具,但我不喜欢在使用Selenium时实际上会打开浏览器。一定有更简单的方法。
谢谢!
添加:
经过一番研究,我发现您仍然可以使用我正在使用的请求包进行操作。这似乎是html中的相关部分:
<option value="0">Select Brand</option>,
<option value="82"> Group</option>,
<option value="17">Alfa Romeo</option>,
<option value="1">Alpina</option>,
<option value="249">Alpine</option>,
<option value="2">Aston Martin</option>,
<option value="67">Audi</option>,
但仍然不知道如何填写该表格。
答案 0 :(得分:0)
有一种解决方法,可以使用pandas read_html从html读取表。只需几行即可将表格html传递到pandas DataFrame中。
对我来说, http://carsalesbase.com/?hide-value=1&brand-option=17&model-option=2089&css-go=Go不返回响应。
import requests
import lxml
from lxml import html
import pandas as pd
import html5lib
from bs4 import BeautifulSoup
from tabulate import tabulate
url = "http://carsalesbase.com/european-car-sales-data/alfa-romeo/"
r = requests.get(url)
tree = html.fromstring(r.content)
tables = tree.xpath('//table')
for table in tables:
df = pd.read_html(html.tostring(table), header=0)
df = df[0]
print(tabulate(df, headers='keys', tablefmt='psql'))
以下打印:
---+--------------+--------------------------+---------------+
| | Unnamed: 0 | Alfa Romeo All Models | MarketShare |
|----+--------------+--------------------------+---------------|
| 0 | 2018 | 83.438 | 0,00% |
| 1 | 2017 | 86.805 | 0,56% |
| 2 | 2016 | 66.155 | 0,44% |
| 3 | 2015 | 56.688 | 0,40% |
| 4 | 2014 | 58.976 | 0,46% |
| 5 | 2013 | 64.285 | 0,52% |
| 6 | 2012 | 90.145 | 0,72% |
| 7 | 2011 | 131.385 | 0,95% |
| 8 | 2010 | 110.654 | 0,79% |
| 9 | 2009 | 110.827 | 0,76% |
| 10 | 2008 | 102.183 | 0,71% |
| 11 | 2007 | 144.404 | 0,92% |
| 12 | 2006 | 145.171 | 0,93% |
| 13 | 2005 | 130.922 | 0,81% |
| 14 | 2004 | 158.195 | 0,98% |
| 15 | 2003 | 159.611 | 1,11% |
| 16 | 2002 | 169.82 | 1,16% |
| 17 | 2001 | 205.431 | 1,36% |
| 18 | 2000 | 176.389 | 1,17% |
| 19 | 1999 | 180.154 | 1,18% |
| 20 | 1998 | 172.675 | 1,19% |
| 21 | 1997 | 128.107 | 0,95% |
| 22 | 1996 | 117.543 | 0,92% |
| 23 | 1995 | 130.358 | 1,08% |
| 24 | 1994 | 101.548 | 0,85% |
| 25 | 1993 | 114.292 | 1,02% |
| 26 | 1992 | 156.184 | 1,16% |
| 27 | 1991 | 180.035 | 1,34% |
| 28 | 1990 | 203.787 | 1,51% |
答案 1 :(得分:0)
想出了解决方法。我看到第二个下拉列表由Java脚本填充。该脚本根据您在第一个下拉菜单中选择的内容生成了第二个下拉菜单的可能条目。
但是第二个下拉列表中的数据存储在该网站上的另一个Java脚本中。
因此,我在HTML中抓取了所有“脚本”标签,直到找到包含所需数据的标签为止。我可以以编程方式打开该脚本,然后将数据从脚本内部传输到我的主要python脚本。
这样,我可以遍历以下http方案:
http://carsalesbase.com/?hide-value=1&brand-option=17&model-option=2089&css-go=Go
这是一个非常专业的解决方案,很显然,您需要硒或与使用JS抓取网站相当的产品。 但是对于我的问题,这就足够了。