我想消除一些重复的代码。任何人都可以使这段代码更短,更好吗?
switch (now.site)
{
case item.SITE.AMAZON:
try
{
price = driver.FindElement(By.XPath("//*[@id=\"priceblock_ourprice\"]")).Text;
fetched = true;
}
catch
{
try
{
price = driver.FindElement(By.XPath("//*[@id=\"priceblock_dealprice\"]")).Text;
fetched = true;
}
catch
{
fetched = false;
}
}
break;
case item.SITE.ALI:
try
{
price = driver.FindElement(By.XPath("//*[@id=\"j-sku-discount-price\"]")).Text;
fetched = true;
}
catch
{
try
{
price = driver.FindElement(By.XPath("//*[@id=\"j-sku-price\"]")).Text;
fetched = true;
}
catch
{
fetched = false;
}
}
break;
}
}
答案 0 :(得分:7)
您可以创建可用路径字符串的字典。我不知道site
是什么类型。我假设string
private static Dictionary<string, string[]> pricePaths = new Dictionary<string, string[]> {
[item.SITE.AMAZON] = new string[] { "//*[@id=\"priceblock_ourprice\"]",
"//*[@id=\"priceblock_dealprice\"]" },
[item.SITE.ALI] = new string[] { "//*[@id=\"j-sku-discount-price\"]",
"//*[@id=\"j-sku-price\"]" },
};
以此,您可以编写更通用的逻辑。
bool fetched = false;
if (pricePaths.TryGetValue(now.site, out string[] paths)) {
foreach (string path in paths) {
try {
price = driver.FindElement(By.XPath(path)).Text;
fetched = true;
break;
} catch {
}
}
}
它使您可以轻松添加新站点。这些站点可以具有任意数量的备用路径。
答案 1 :(得分:0)
看来您实际上是在尝试获取十进制值。让我们使用此假设,并创建一个返回decimal?
来指示成功(即值)或失败(即null
)的方法。
public static class Ex
{
public static decimal? FindDecimalMaybe(this IWebDriver driver, string path)
{
try
{
if (decimal.TryParse(driver.FindElement(By.XPath(path)).Text, out decimal result))
{
return result;
}
}
catch { } // I hate this, but there doesn't seem to be a choice
return null;
}
}
此方法的目的是隐藏Selenium库似乎是异常编码的令人不愉快的事实。
我还创建了它作为扩展方法,以便将driver.FindElement
的调用替换为看起来很熟悉的东西-driver.FindDecimalMaybe
。
现在,我使用与Oliver相同的方法来制作字典:
private static Dictionary<string, string[]> __pricePaths = new Dictionary<string, string[]>
{
{ item.SITE.AMAZON, new [] { "//*[@id=\"priceblock_ourprice\"]", "//*[@id=\"priceblock_dealprice\"]" } },
{ item.SITE.ALI, new [] { "//*[@id=\"j-sku-discount-price\"]", "//*[@id=\"j-sku-price\"]" } },
};
现在,获取值很简单:
decimal? price =
__pricePaths[now.site]
.Select(path => driver.FindDecimalMaybe(path))
.Where(x => x.HasValue)
.FirstOrDefault();
如果price
变量具有值,则成功,但是如果变量null
,则调用未成功。
答案 2 :(得分:-1)
有关如何美化代码的一些建议-
从每种情况下删除try捕获,然后调用该函数以从常量集中传递正确的xPath字符串。
const string priceblock_ourprice = "//*[@id=\"priceblock_ourprice\"]";
const string priceblock_dealprice = "//*[@id=\"priceblock_dealprice\"]";
const string j_sku_discount_price = "//*[@id=\"j-sku-discount-price\"]";
const string j_sku_price = "//*[@id=\"j-sku-price\"]";
public void YourPrimaryFunction
{
decimal price;
switch (now.site)
{
case item.SITE.AMAZON:
fetched = FetchPrice(priceblock_ourprice, priceblock_dealprice, out price);
break;
case item.SITE.ALI:
fetched = FetchPrice(j_sku_discount_price, j_sku_price, out price);
break;
}
}
private bool FetchPrice(string xPathPrim, string xPathFallBack, decimal out price)
{
try
{
price = driver.FindElement(By.XPath(xPathPrim)).Text;
return true;
}
catch
{
try
{
price = driver.FindElement(By.XPath(xPathFallBack)).Text;
return true;
}
catch
{
return false;
}
}
}