Я работаю над веб-сканером, который посещает страницу и извлекает ссылку для поиска определенного домена, если он не находит его, просматривает извлеченные ссылки и повторяет их, пока не достигнет предела страницы или не найдет страницу. Я пытаюсь придумать разумную логику, чтобы бот продолжал ставить задачи в очередь после того, как он извлекает ссылки, потому что задачи выполняются быстро и недостаточно времени для отправки вновь извлеченных ссылок. Как я могу реализовать реализацию, чтобы сканер ждал, пока у него не останется больше ссылок, прежде чем завершить работу исполнителя? Я включил базовый обзор моей многопоточной реализации. Я установил максимальное количество потоков равным 3 и 10 раз отправляю example.com (домены Seed)
Spawn Thread посещает сайт и извлекает ссылки, а затем возвращает их в строку. Моя проблема в том, что я должен быть в состоянии взять эти результаты и затем поместить их в очередь. Но очередь к этому времени уже закончилась. Какие-либо предложения?
Обновление Итак, чтобы уточнить, моя проблема в том, что когда я отправляю семя и получаю результаты, я не могу заставить его продолжить поиск возвращенных семян.
Если я не блокирую и не жду результатов, а затем добавляю их вручную.
Обновление 2 Чтобы уточнить немного, я пытаюсь предотвратить блокировку на future.get
, чтобы я мог добавить возвращаемые результаты по мере их
должны быть запланированы как задачи.
int MaxThreads = 3;
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(MaxThreads); // How many threads
List<Future<String>> resultList = new ArrayList<>();// Create results list
for (int i = 0; i < 10; i ++) {
SpawnThread task = new SpawnThread("example.com");// Create Tasks
Future<String> result = executor.submit(task);//Launch tasks
//System.out.println("Added " + CurrentNum + " to the que!");
resultList.add(result);//Store Task Result
}
for(Future<String> future : resultList) //Loop through results
{
String resultfinished;
try {
resultfinished = future.get();
System.out.println(resultfinished);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
executor.shutdown();
Я думаю, что мне нужна неблокирующая очередь для результатов, которая может
быть добавлен обратно в список, который дает новые домены для сканирования, но
Я не могу заставить его работать.
BlockingQueue queue = new ArrayBlockingQueue(1024);
Executor executor = Executors.newFixedThreadPool(4);
CompletionService<List<String>> completionService =
new ExecutorCompletionService<List<String>>(executor);
List<String> pagesToVisit = new ArrayList<String>();
Set<String> pagesVisited = new HashSet<String>();
String SeedPage = "https://example.com/";
String currentURL = null;
boolean done = false;
while(!done) {
int listsize = pagesToVisit.size();
if(pagesToVisit.isEmpty())
{
currentURL = SeedPage;
pagesVisited.add(SeedPage);
listsize = pagesToVisit.size() + 1;
}
else
{
currentURL = nextUrl();
}
for(int k = 0; k < listsize; k ++)
{
completionService.submit(new Spider(currentURL,"IP","PORT" ) {
});
}
int received = 0;
boolean errors = false;
while(received < listsize && !errors)
{
Thread.sleep(1000);
Future<List<String>> resultFuture = completionService.take(); //blocks if none available
try
{
List<String> result = resultFuture.get();
pagesToVisit.addAll(result);
received ++;
}
catch(Exception e)
{
//log
e.printStackTrace();
errors = true;
}
}
}