我已经编写了代码,用于在java中使用selenium webdriver找出网站中存在的断开的链接。在启动不同的网址时,HashSet
中会添加链接。我试图从HashSet
读取添加的URL,它会在一段时间后停止执行。发生这种情况是因为迭代器仍然存在,因为它甚至添加了HashSet
的新链接。我希望对HashSet
中存在的所有链接继续执行。
[我试图将Set
转换为数组,但重复的链接正在执行多次。]
public Set<String> unique_links;
HashMap<String, String> result;
Set<String> finalLinkSet = new HashSet<>();
Set<String> hs = new HashSet<>();
Set<String> uniqueLinkSet = new HashSet<>();
// String[] finalLinkArray;
String[] finalLinkArray;
boolean isValid = false;
FileWriter fstream;
BufferedWriter out;
int count = 1;
int FC = 0;
Set<String> secondaryset = new HashSet<>();
// String Responsecode = null;
@Test
public void LinkTesting() throws IOException, RowsExceededException,
WriteException {
w.manage().deleteAllCookies();
unique_links = new HashSet<String>();
w.get("http://www.skyscape.com");
ArrayList<WebElement> urlList = new ArrayList<WebElement>();
urlList = (ArrayList<WebElement>) w.findElements(By.tagName("a"));
setFinalLinkSet(getUniqueList(urlList));
for(Iterator<String> i = finalLinkSet.iterator(); i.hasNext(); ) {
System.out.println(finalLinkSet.size());
String currenturl = (String) i.next();
if ((currenturl.length() > 0 && currenturl
.startsWith("http://www.skyscape.com"))) {
if (!currenturl.startsWith("http://www.skyscape.com/estore/")&&
(!currenturl.startsWith("http://www.skyscape.com/demos/"))) {
System.out.println(currenturl);
getResponseCode(currenturl);
}
}
}
writetoexcel();
}
public void setFinalLinkSet(Set<String> finalLinkSet) {
this.finalLinkSet = finalLinkSet;
}
// function to get link from page and return array list of links
public Set<String> getLinksOnPage(String url) {
ArrayList<WebElement> secondaryUrl = new ArrayList<WebElement>();
secondaryUrl = (ArrayList<WebElement>) w.findElements(By.tagName("a"));
for (int i = 0; i < secondaryUrl.size(); i++) {
secondaryset.add((secondaryUrl.get(i).getAttribute("href")
.toString()));
}
return secondaryset;
}
// function to fetch link from array list and store unique links in hashset
public Set<String> getUniqueList(ArrayList<WebElement> url_list) {
for (int i = 0; i < url_list.size(); i++) {
uniqueLinkSet.add(url_list.get(i).getAttribute("href").toString());
}
return uniqueLinkSet;
}
public boolean getResponseCode(String url) {
boolean isValid = false;
if (result == null) {
result = new HashMap<String, String>();
}
try {
URL u = new URL(url);
w.navigate().to(url);
HttpURLConnection h = (HttpURLConnection) u.openConnection();
h.setRequestMethod("GET");
h.connect();
System.out.println(h.getResponseCode());
if ((h.getResponseCode() != 500) && (h.getResponseCode() != 404)
&& (h.getResponseCode() != 403)
&& (h.getResponseCode() != 402)
&& (h.getResponseCode() != 400)
&& (h.getResponseCode() != 401)) {
// && (h.getResponseCode() != 302)) {
//getLinksOnPage(url);
Set<String> unique2 = getLinksOnPage(url);
setFinalLinkSet(unique2);
result.put(url.toString(), "" + h.getResponseCode());
} else {
result.put(url.toString(), "" + h.getResponseCode());
FC++;
}
return isValid;
} catch (Exception e) {
}
return isValid;
}
private void writetoexcel() throws IOException, RowsExceededException,
WriteException {
FileOutputStream fo = new FileOutputStream("OldLinks.xls");
WritableWorkbook wwb = Workbook.createWorkbook(fo);
WritableSheet ws = wwb.createSheet("Links", 0);
int recordsToPrint = result.size();
Label HeaderUrl = new Label(0, 0, "Urls");
ws.addCell(HeaderUrl);
Label HeaderCode = new Label(1, 0, "Response Code");
ws.addCell(HeaderCode);
Label HeaderStatus = new Label(2, 0, "Status");
ws.addCell(HeaderStatus);
Iterator<Entry<String, String>> it = result.entrySet().iterator();
while (it.hasNext() && count < recordsToPrint) {
String Responsecode = null;
Map.Entry<String, String> pairs = it.next();
System.out.println("Value is --" + pairs.getKey() + " - "
+ pairs.getValue() + "\n");
Label Urllink = new Label(0, count, pairs.getKey());
Label RespCode = new Label(1, count, pairs.getValue());
Responsecode = pairs.getValue();
System.out.println(Responsecode);
if ((Responsecode.equals("500")) || (Responsecode.equals("404"))
|| (Responsecode.equals("403"))
|| (Responsecode.equals("400"))
|| (Responsecode.equals("402"))
|| (Responsecode.equals("401"))) {
// || (Responsecode.equals("302"))) {
Label Status1 = new Label(2, count, "Fail");
ws.addCell(Status1);
} else {
Label Status2 = new Label(2, count, "Pass");
ws.addCell(Status2);
}
try {
ws.addCell(Urllink);
} catch (RowsExceededException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}
ws.addCell(RespCode);
count++;
}
Label FCS = new Label(4, 1, "Fail Urls Count is = " + FC);
ws.addCell(FCS);
wwb.write();
wwb.close();
}
}
答案 0 :(得分:0)
简而言之,就我理解的问题而言:你有(至少)两个线程(尽管我在太长的代码示例中找不到它们),一个是向HashSet添加条目,并且其他应该在将元素添加到HashSet时连续列出元素。 第1步:您应该为此使用并发数据结构,但不是简单的HashSet。 第二:HashSet的迭代器不支持并发修改,因此你现在可以拥有一个迭代器&#34; waiting&#34;添加新条目。
最好是将代码更改为使用某种事件消息模式(有时也称为广播/侦听器),其中查找新URL会生成事件,代码的其他部分会侦听然后编写它们到文件。
答案 1 :(得分:0)
您的循环结束(早于期望),原因如下:
for循环
的初始部分Iterator<String> i = finalLinkSet.iterator()
for(Iterator<String> i = finalLinkSet.iterator(); i.hasNext(); ) {
启动循环时,将评估一次。因此,即使在某些地方,也不会对finalLinkSet
的更改做出反应。
您未对finalLinkSet
进行任何更改。而是在调用
setFinalLinkSet(unique2);
所以你应该:
ArrayList<String>
,因此您可以通过性能的小缺点获得持续访问时间,以便在添加新条目时调整大小。修改你的for循环以使用索引,所以一次评估init-part就足够了,你可以对列表大小的变化做出反应:
for(int i = 0; i < finalLinkList.size(); i++) {
System.out.println(finalLinkSet.size());
String currenturl = (String) finalLinkList.get(i);
然后,您应该:
而不是覆盖列表// for both occurrences
addToFinalLinkList(...); // see new code below
和
public void addToFinalLinkList(Set<String> tempSet) {
for(String url: tempSet)
{
if(!finalLinkList.contains(url))
finalListList.add(url);
}
}
从性能的角度来看,我知道这不是最好的,但是因为你在测试中,所以这不应该是我所看到的问题......