今天早上,我决定我想做一个小项目,将maverik加油站的所有汽油价格解析为一个数组。我可以轻松地完成大部分工作,我觉得代码中唯一“脏”的部分是将html实际解析为变量。我正在使用indexOf和子字符串来获取所需的数据,我觉得必须有一种更清洁的方式来做到这一点?无论如何,这是我的代码,它可以编译并很好地工作,只是没有我想要的那么干净。
maverik.java包含项目的主要方法和大量代码。
maverikObj.java包含getter和setter,构造函数和toString方法。
要更改加油站,您可以从中获取控制台数据,只需在maverik.java的第90行更改数组println中的数字即可。将来的修订版将提供一些方法来控制根据用户请求显示哪些数据。
这是带有价格的HTML示例:
html4 = "<b>Maverik Store 4</b><br/>5200 Chinden Blvd<br>Boise, ID<br>208-376-0532<br><center><b></b></center><br /><font color=red>Fuel Prices -- Updated every 30 minutes</font><br /><div><div style=\"float: left; width: 70%; text-align:right;\">Adventure Club Card</div><div style=\"float: right; width: 30%; text-align:center;\">Retail</div><br /><div style=\"float: left;width: 30%;\">Unleaded:</div><div style=\"float: left; width: 30%; text-align:center;\"> 3.379</div><div style=\"float: right; width: 30%; text-align:center;\"> 3.399</div><br /><div style=\"float: left;width: 30%;\">Blend 89:</div><div style=\"float: left; width: 30%; text-align:center;\"> 3.469</div><div style=\"float: right; width: 30%; text-align:center;\"> 3.499</div><br /><div style=\"float: left;width: 30%;\">Blend 90:</div><div style=\"float: left; width: 30%; text-align:center;\"> 3.549</div><div style=\"float: right; width: 30%; text-align:center;\"> 3.579</div><br /><div style=\"float: left;width: 30%;\">Premium:</div><div style=\"float: left; width: 30%; text-align:center;\"> 3.599</div><div style=\"float: right; width: 30%; text-align:center;\"> 3.639</div><br /><div style=\"float: left;width: 30%;\">Diesel:</div><div style=\"float: left; width: 30%; text-align:center;\"> 4.039</div><div style=\"float: right; width: 30%; text-align:center;\"> 4.059</div>";
目前,我正在解析地址,城市,州,电话号码以及每个站点可能的8种气体类型。 (无铅,混合87,88,89,99,优质,柴油)。但是,由于有些html条目没有列出的所有8种html条目,所以有点棘手,而大多数html条目只有8种可能的4种或5种。因此,我使用两种方法来解析此数据。
地址,城市,州,电话号码使用以下方式解析:
if(line.contains(" = \"<b>Maverik Store")&&!line.contains("Coming Soon!")){ address=splitLine[3].substring(0,splitLine[3].length()-3).replace(" ", " "); city=splitLine[4].substring(0,splitLine[4].length()-7); state=splitLine[4].substring(splitLine[4].length()-5,splitLine[4].length()-3); phone=splitLine[5].substring(0,splitLine[5].length()-3);
燃料类型使用if else语句进行解析,使用if语句记录数据(如果存在),而else语句记录0.0倍的数据,因为我的构造函数要求所有燃料类型都具有一定的值。
if(line.indexOf("Unleaded:")>0){
unleaded=Double.parseDouble(line.substring(line.indexOf("Unleaded:")+147, line.indexOf("Unleaded:")+152));
}
else{
unleaded=0.0;
}
如您所见,我使用许多子字符串和indexOf字符串方法来获取所需的数据。我担心这是获取所需数据的极其静态的方法,因此我觉得这是一种非常肮脏的处理方式。感谢有关如何清理代码的任何提示! =)
最佳答案
您可以使用如下正则表达式:
BufferedReader reader = new BufferedReader (
new InputStreamReader (
new URL ("https://www.maverik.com/locations/").
openStream ()));
Pattern linePattern = Pattern.compile ("<b>Maverik Store ([^<]*)</b><br/>([^<]*)<br>([^<]*)<br>([^<]*)<br><center><b></b></center><br /><font color=red>Fuel Prices -- Updated every 30 minutes</font>");
Pattern pricePattern = Pattern.compile ("<div style=\\\\\"float: left;width: 30%;\\\\\">([^<]*)</div><div style=\\\\\"float: left; width: 30%; text-align:center;\\\\\">([^<]*)</div><div style=\\\\\"float: right; width: 30%; text-align:center;\\\\\">([^<]*)</div><br />");
String line;
while ((line = reader.readLine ()) != null)
{
Matcher lineMatcher = linePattern.matcher (line);
if (lineMatcher.find ())
{
System.out.println ("Store #: " + lineMatcher.group (1));
System.out.println ("Store Address 1: " + lineMatcher.group (2));
System.out.println ("Store Address 2: " + lineMatcher.group (3));
System.out.println ("Store Phone: " + lineMatcher.group (4));
Matcher priceMatcher = pricePattern.matcher (line);
while (priceMatcher.find ())
{
System.out.println (priceMatcher.group (1) + priceMatcher.group (2) + priceMatcher.group (3));
}
System.out.println ();
}
}
对我来说,它输出:
Store #: 4
Store Address 1: 5200 Chinden Blvd
Store Address 2: Boise, ID
Store Phone: 208-376-0532
Unleaded: 3.379 3.399
Blend 89: 3.469 3.499
Blend 90: 3.549 3.579
Premium: 3.599 3.639
Store #: 6
Store Address 1: 8561 West State
Store Address 2: Boise, ID
Store Phone: 208-853-1226
Unleaded: 3.379 3.399
Blend 88: 3.849 3.879
Blend 89: 3.469 3.499
Blend 90: 3.549 3.579
Store #: 7
Store Address 1: Highway 310 North
Store Address 2: Bridger, MT
Store Phone: 406-662-3356
Unleaded: 3.249 3.269
Blend 87: 3.499 3.529
Blend 89: 3.499 3.529
Premium: 3.489 3.529
Store #: 130
Store Address 1: 105 South 200 West
Store Address 2: Bountiful, UT
Store Phone: 801-292-6792
Unleaded: 3.269 3.289
Blend 87: 3.359 3.389
Blend 89: 3.439 3.469
Store #: 134
Store Address 1: 105 East Winnemucca
Store Address 2: Winnemucca, NV
Store Phone: 775-623-5948
Unleaded: 3.559 3.579
Blend 87: 3.649 3.679
Blend 89: 3.729 3.759
Store #: 135
Store Address 1: 1571 North Main
Store Address 2: Sheridan, WY
Store Phone: 307-672-7010
Unleaded: 3.159 3.179
Store #: 136
Store Address 1: 222 South Main
Store Address 2: Lyman, WY
Store Phone: 307-786-2705
Unleaded: 3.269 3.289
Blend 87: 3.359 3.389
Blend 89: 3.439 3.469
Premium: 3.489 3.529
Store #: 137
Store Address 1: 7th & Main
Store Address 2: Snowflake, AZ
Store Phone: 928-536-7511
Unleaded: 3.539 3.559
Blend 89: 3.629 3.659
Blend 90: 3.709 3.739
...