从多个sitemap.xml文件中搜寻网址

时间:2019-08-27 12:07:25

标签: apify

我正在为页面构建一个合适的参与者,其中所有需要的URL存储在不同的sitemap.xml文件中。这些文件名是静态的,但无法确定如何向角色添加多个sitemap.xml文件。

下面是具有1个xml文件的工作代码。不知何故需要对多个URL进行逐个访问,但是由于其中有大约600个,因此最好通过诸如从csv提取所有站点地图,然后对每个URL进行爬网,然后对每个URL进行爬网这样的方式来实现。 >

ID

每个sitemap.xml都有一个静态链接/名称,但是它们的内容每天都在变化,并且站点地图中的URL总数为60-70.000,这是我最终需要获取的URL:-)

1 个答案:

答案 0 :(得分:0)

最可靠的方法是使用Apify Crawler classes的功能。当然,有很多方法可以解决这个问题。

最简单的解决方案是使用一个CheerioCrawler,并在handlePageFunction中使用单独的逻辑来表示站点地图URL和最终URL。不幸的是,CheerioCrawler无法解析XML(可能会在不久的将来得到修复),因此我们将不得不使用2个搜寻器。

对于XML解析的第一部分,我们将使用BasicCrawler。它是Apify搜寻器中最通用的爬虫,因此可以轻松使用您已有的代码。我们将提取的URL推送到requestQueue,并在第二个搜寻器中进行处理,该搜寻器可以保持原样。

const Apify = require('apify');
const cheerio = require('cheerio');
const requestPromised = require('request-promise-native');

Apify.main(async () => {

    // Here we will push the URLs found in the sitemaps
    const requestQueue = await Apify.openRequestQueue();

    // This would be better passed via INPUT as `const xmlUrls = await Apify.getInput().then((input => input.xmlUrls))`
    const xmlUrls = [
        'https://www.website.com/sitemap1.xml',
        // ...
    ]

    const xmlRequestList = new Apify.RequestList({
        sources: xmlUrls.map((url) => ({ url })) // We make smiple request object from the URLs
    })

    await xmlRequestList.initialize();

    const xmlCrawler = new Apify.BasicCrawler({
        requestList: xmlRequestList,
        handleRequestFunction: async ({ request }) => {
            // This is basically the same code you have, we just have to push the sources to the queue
            const xml = await requestPromised({
                url: request.url,
                headers: {
                    'User-Agent': 'curl/7.54.0'
                }
            });

            const $ = cheerio.load(xml);
            const sources = [];
            $('loc').each(function (val) {
                const url = $(this).text().trim();
                sources.push({
                    url,
                    headers: {
                        // NOTE: Otherwise the target doesn't allow to download the page!
                        'User-Agent': 'curl/7.54.0',
                    }
                });
            });
            for (const finalRequest of sources) {
                await requestQueue.addRequest(finalRequest);
            }
        }
    })

    await xmlCrawler.run()

    // Crawl each page from sitemap
    const crawler = new Apify.CheerioCrawler({
        requestQueue,
        handlePageFunction: async ({ $, request }) => {
            // Add your logic for final URLs
            await Apify.pushData({
                url: request.url
            });
        },
    });

    await crawler.run();
    console.log('Done.');
});