Как отправить данные crawler4j в CrawlerManager? - PullRequest
0 голосов
/ 22 ноября 2018

Я работаю с проектом, в котором пользователь может искать на некоторых веб-сайтах и ​​искать изображения с уникальным идентификатором.

public class ImageCrawler extends WebCrawler {

private static final Pattern filters = Pattern.compile(
        ".*(\\.(css|js|mid|mp2|mp3|mp4|wav|avi|mov|mpeg|ram|m4v|pdf" +
                "|rm|smil|wmv|swf|wma|zip|rar|gz))$");

private static final Pattern imgPatterns = Pattern.compile(".*(\\.(bmp|gif|jpe?g|png|tiff?))$");

public ImageCrawler() {
}

@Override
public boolean shouldVisit(Page referringPage, WebURL url) {
    String href = url.getURL().toLowerCase();
    if (filters.matcher(href).matches()) {
        return false;
    }

    if (imgPatterns.matcher(href).matches()) {
        return true;
    }

    return false;
}

@Override
public void visit(Page page) {
    String url = page.getWebURL().getURL();

    byte[] imageBytes = page.getContentData();
    String imageBase64 = Base64.getEncoder().encodeToString(imageBytes);
    try {
        SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(urlScan.getOwner(), null));
        DecodePictureResponse decodePictureResponse = decodePictureService.decodePicture(imageBase64);
        URLScanResult urlScanResult = new URLScanResult();
        urlScanResult.setPicture(pictureRepository.findByUuid(decodePictureResponse.getPictureDTO().getUuid()).get());
        urlScanResult.setIntegrity(decodePictureResponse.isIntegrity());
        urlScanResult.setPictureUrl(url);
        urlScanResult.setUrlScan(urlScan);
        urlScan.getResults().add(urlScanResult);
        urlScanRepository.save(urlScan);
    }

    } catch (ResourceNotFoundException ex) {
        //Picture is not in our database
    }
}

Программы-обходчики будут работать независимо.Класс ImageCrawlerManager, который является синглетным, запускает сканеры.

public class ImageCrawlerManager {

private static ImageCrawlerManager instance = null;


private ImageCrawlerManager(){
}

public synchronized static ImageCrawlerManager getInstance()
{
    if (instance == null)
    {
        instance = new ImageCrawlerManager();
    }
    return instance;
}

@Transactional(propagation=Propagation.REQUIRED)
@PersistenceContext(type = PersistenceContextType.EXTENDED)
public void startCrawler(URLScan urlScan, DecodePictureService decodePictureService, URLScanRepository urlScanRepository, PictureRepository pictureRepository){

    try {
        CrawlConfig config = new CrawlConfig();
        config.setCrawlStorageFolder("/tmp");
        config.setIncludeBinaryContentInCrawling(true);

        PageFetcher pageFetcher = new PageFetcher(config);
        RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
        RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);

        CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);
        controller.addSeed(urlScan.getUrl());

        controller.start(ImageCrawler.class, 1);
        urlScan.setStatus(URLScanStatus.FINISHED);
        urlScanRepository.save(urlScan);
    } catch (Exception e) {
        e.printStackTrace();
        urlScan.setStatus(URLScanStatus.FAILED);
        urlScan.setFailedReason(e.getMessage());
        urlScanRepository.save(urlScan);
    }
}

Как отправить все данные изображения менеджеру, который декодирует это изображение, получить инициатор поиска и сохранить результаты в базе данных?В приведенном выше коде я могу запустить несколько сканеров и сохранить его в базе данных.Но, к сожалению, когда я запускаю два сканера одновременно, я могу сохранить два результата поиска, но все они подключены к сканеру, который был запущен первым.

1 Ответ

0 голосов
/ 07 декабря 2018

Вы должны внедрить вашу службу базы данных в ваши ẀebCrawler экземпляры и не использовать одноэлементное управление для управления результатами вашего веб-сканирования.

crawler4j поддерживает пользовательский CrawlController.WebCrawlerFactory (см. здесь для справки), который может использоваться с Spring для внедрения службы базы данных в экземпляр ImageCrawler.

Каждый отдельный поток искателя должен отвечать за весь процесс, который выописывается с помощью (например, с использованием некоторых специальных сервисов для него):

декодировать это изображение, получить инициатор поиска и сохранять результаты в базе данных

Настроить его такваша база данных будет единственным источником истины , и вам не придется иметь дело с синхронизацией состояний искателя между различными экземплярами или сеансами пользователя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...