- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我需要编写一个网络抓取工具来抓取大约 100 万个网站并将它们的标题、描述和关键字保存到一个大文件中(包含抓取的 URL 和相关词)。应该从一个大文件中提取 URL。
我已经在 1M 的 URL 文件上运行了 Crawler4j,并使用以下代码启动了网络爬虫:controller.start(MyCrawler.class, 20)
。 20 是一个任意数字。每个爬虫将结果词传递到一个阻塞队列中,以便单个线程将这些词和 URL 写入文件。为了不在文件上同步,我使用了 1 个编写器线程。我设置爬取深度为0(我只需要爬取我的种子列表)
运行一整晚之后,我只下载了大约 200K 个 URL。我使用有线连接在一台机器上运行爬虫。由于大多数 URL 属于不同的主机,因此我认为礼貌参数在这里没有任何重要性。
编辑
我尝试使用非阻塞启动方式启动 Crawler4j,但它被阻塞了。我的 Crawler4j 版本是:4.2。这是我正在使用的代码:
CrawlConfig config = new CrawlConfig();
List<Header> headers = Arrays.asList(
new BasicHeader("Accept", "text/html,text/xml"),
new BasicHeader("Accept-Language", "en-gb, en-us, en-uk")
);
config.setDefaultHeaders(headers);
config.setCrawlStorageFolder(crawlStorageFolder);
config.setMaxDepthOfCrawling(0);
config.setUserAgentString("testcrawl");
config.setIncludeBinaryContentInCrawling(false);
config.setPolitenessDelay(10);
PageFetcher pageFetcher = new PageFetcher(config);
RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
BlockingQueue<String> urlsQueue = new ArrayBlockingQueue<>(400);
controller = new CrawlController(config, pageFetcher, robotstxtServer);
ExecutorService executorService = Executors.newSingleThreadExecutor();
Runnable writerThread = new FileWriterThread(urlsQueue, crawlStorageFolder, outputFile);
executorService.execute(writerThread);
controller.startNonBlocking(() -> {
return new MyCrawler(urlsQueue);
}, 4);
File file = new File(urlsFileName);
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String url;
while ((url = br.readLine()) != null) {
controller.addSeed(url);
}
}
编辑 1 - 这是 MyCrawler 的代码
public class MyCrawler extends WebCrawler {
private final static Pattern FILTERS = Pattern.compile(".*(\\.(css|js|gif|jpg|png|mp3|mp3|zip|gz))$");
public static final String DELIMETER = "||||";
private final StringBuilder buffer = new StringBuilder();
private final BlockingQueue<String> urlsQueue;
public MyCrawler(BlockingQueue<String> urlsQueue) {
this.urlsQueue = urlsQueue;
}
@Override
public boolean shouldVisit(Page referringPage, WebURL url) {
String href = url.getURL().toLowerCase();
return !FILTERS.matcher(href).matches();
}
@Override
public void visit(Page page) {
String url = page.getWebURL().getURL();
if (page.getParseData() instanceof HtmlParseData) {
HtmlParseData parseData = (HtmlParseData) page.getParseData();
String html = parseData.getHtml();
String title = parseData.getTitle();
Document document = Jsoup.parse(html);
buffer.append(url.replaceAll("[\n\r]", "")).append(DELIMETER).append(title);
Elements descriptions = document.select("meta[name=description]");
for (Element description : descriptions) {
if (description.hasAttr("content"))
buffer.append(description.attr("content").replaceAll("[\n\r]", ""));
}
Elements elements = document.select("meta[name=keywords]");
for (Element element : elements) {
String keywords = element.attr("content").replaceAll("[\n\r]", "");
buffer.append(keywords);
}
buffer.append("\n");
String urlContent = buffer.toString();
buffer.setLength(0);
urlsQueue.add(urlContent);
}
}
private boolean isSuccessful(int statusCode) {
return 200 <= statusCode && statusCode < 400;
}
}
所以我有两个问题:
crawler.startNonBlocking
,但它似乎工作得不是很好提前致谢
最佳答案
crawler4j
默认设计为在一台机器上运行。从网络爬虫
领域我们知道,网络爬虫的性能主要取决于以下四种资源:
定义最佳线程数取决于您的硬件设置。因此,更多的机器将导致更高的吞吐量。下一个硬限制是网络带宽。如果您没有通过高速互联网连接,这将成为您方法的瓶颈。
此外,crawler4j
并非设计用于默认加载如此巨大的种子文件。这是因为 crawler4j
尊重爬虫策略。这意味着,在抓取开始之前,每个种子点都将被检查是否有 robots.txt
,这可能会花费相当多的时间。
如果以非阻塞模式启动爬网,则在启动爬网后添加种子是可能的并且应该有效。但是,处理 URL 可能需要一段时间。
对于多机设置,您可以查看 Apache Nutch .然而,Nutch 有点难学。
编辑:
重现您的设置后,我能够以动态方式回答您关于添加种子页面的问题。
以这种方式启动爬虫
controller.startNonBlocking(() -> {
return new MyCrawler(urlsQueue);
}, 4);
将调用每个爬虫线程的 run()
方法。研究这个方法,我们发现一个名为 frontier.getNextURLs(50, assignedURLs);
的方法,它负责从 frontier 中获取看不见的 URL 以便处理它们。在这个方法中,我们找到了一个所谓的waitingList
,它会导致线程等待。由于 notifyAll
永远不会在 waitingList
上调用,直到 Controller 关闭,线程永远不会重新安排新的 URL。
要克服这个问题,您有两种可能的解决方案:
只需为每个线程添加至少一个 URL 作为种子点。不会出现死锁情况。以非阻塞模式启动线程后,您可以随意添加种子。
controller.addSeed("https://www.google.de");
controller.startNonBlocking(() -> {
return new MyCrawler(urlsQueue);
}, 4);
controller.addSeed("https://www.google.de/test");
controller.waitUntilFinish();
从 Github 项目中获取一个分支并修改 Frontier.java
的代码,以便可以从动态添加种子页面后的 CrawlController
。
关于java - 提高crawler4j的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35405116/
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 8年前关闭。 Improve this q
我最近在准备面试时读了一本书,并遇到了以下问题: 当你的爬虫遇到一个蜜 jar 并生成一个无限子图供你漫步时,你会怎么做? 我想找到这个问题的一些解决方案。就我个人而言,我会采用某种形式的深度有限搜索
我需要抓取一千个共享相同结构的网站:它们都有一个菜单、一个标题、一些文本和一个评级,很像一个博客。不幸的是,它们的编码也非常不同,有些是手动的,所以我不能重新利用 CSS 选择器,甚至可能不依赖它们。
我正在尝试抓取大约一千个网站,其中我只对 html 内容感兴趣。 然后我将 HTML 转换为 XML 以使用 Xpath 进行解析以提取我感兴趣的特定内容。 我已经使用 Heritrix 2.0 爬虫
我想从某些网站抓取有用的资源(如背景图片..)。这不是一项艰巨的工作,尤其是在一些很棒的项目(如scrapy)的帮助下。 这里的问题是我不仅只想抓取这个网站一次。我还想保持我的爬网长时间运行并爬网更新
我是 Nutch 的新手。我需要抓取网页(比如几百个网页),读取抓取的数据并进行一些分析。 我点击了链接 https://wiki.apache.org/nutch/NutchTutorial (并且
我要爬一个网站以获取一些信息。它大约有 170 000 多页。那么,我可以提出多少请求?我要提取直到 HTML 并获取一些信息。这是一个已经很受欢迎的网站,所以我认为如果只是快速浏览所有页面它不会死.
我正在构建一个小型应用程序,它将抓取内容不断增长的站点(如在 stackoverflow 上),不同之处在于一旦创建的内容很少被修改。 现在,在第一遍中,我抓取了站点中的所有页面。 但接下来,该站点的
我在比较这四个 Nutch/Heritrix/OpenPipeLine/Apache Tika 哪一个最好?各自的优缺点是什么? 我想要一些可扩展的爬虫,它可以爬取网站列表,并且可以根据需要进行修改。
正如标题所说,我一直在努力爬取文章,剩下的就是作者。 下面是我的代码,使用pyquery编译段落和作者,只有作者返回空白 目标站点:http://business.transworld.net/153
我正在为旅游搜索引擎考虑一些想法,我想知道这些网站是如何获取它们的源数据的。他们是否从航空公司主页上抓取了所有内容?考虑到航空公司等的数量,这似乎是一项艰巨的工作。 是否有每个航空公司也遵守的 API
我正在测试一个新的网络爬虫,我正在寻找一些可能会绊倒它的好网站(重定向、框架、任何东西)。有人知道一些非常复杂的网站,或者可能会出错的网站吗?谢谢 最佳答案 如果你在 Alexa 前 1000 名左右
有一种方法可以从 google 的索引中排除完整的页面。但是有没有办法专门从谷歌的抓取中排除网页的某些部分?例如,排除通常包含不相关内容的侧边栏? 最佳答案 您可以使用 IFRAME 标记包含要在 G
给定一个起始 URL start (以及关于可允许域等的一些规则)我想生成一个有向图(V,E),其中 V 中的节点是否可以从 start 访问页面,并且有一条弧线 (u,v)在 E每当页面上有超链接时
我正在开发一个Web爬网程序,该爬网程序可以为不想被索引的网站编制索引。 我的第一次尝试: 我编写了一个C#搜寻器,它遍历每个页面并下载它们。 这导致我的IP在10分钟内被其服务器阻塞。 我将其移至A
我想知道用于抓取和分析网站的最佳 eopen-source 库是什么。一个例子是爬虫属性(property)机构,我想从多个站点获取信息并将它们聚合到我自己的站点中。为此,我需要抓取网站并提取属性(p
Builtwith.com 和类似服务提供(收费)使用特定技术(如 SalesForce 或 NationBuilder)构建的域列表。有一些我感兴趣的技术 builtwith 没有扫描,可能是因为它
我正在使用scrapy 来抓取站点上的多个页面。 变量 start_urls用于定义要抓取的页面。 我最初会从第一页开始,从而定义 start_urls = [1st page]在文件中 exampl
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 8年前关闭。 Improve this questi
我有一个实现无限滚动的网站:当用户到达页面末尾时,会进行 AJAX 调用并将新内容附加到页面底部。然而,这意味着搜索爬虫无法获取第一个“分页符”之后的所有内容。例如,我有一个页面列出了所有带有“信息图
我是一名优秀的程序员,十分优秀!