如何修改Cheerio爬虫代码仅获取div下首个<ul>元素内容?
如何仅抓取Reddit页面中guidelines板块下的首个
- 元素?
问题描述
我是Web Scraping新手,此前已通过教程完成简单爬虫开发,现希望自行新增功能。目标页面为https://old.reddit.com/r/programming/,我想要抓取页面右侧“guidelines”板块下的所有项目符号。目前我的代码可抓取“guidelines”“info”“relatedReddits”三个区域的全部信息,但我仅需“guidelines”的内容。请问如何修改代码,使其仅访问div下的首个
- 元素?
当前代码
const axios = require('axios'); const cheerio = require('cheerio'); const getPostTitles = async () => { try{ const {data} = await axios.get('https://old.reddit.com/r/programming/'); const $ = cheerio.load(data); const guidelines = []; const postTitles = []; $('p.title > a').each((idx, el) => { const postTitle = $(el).text(); postTitles.push(postTitle); }); $('.md ul li').each((idx, el) => { const guideline = $(el).text(); guidelines.push(guideline); }); console.log(guidelines); return postTitles; } catch(error){ throw error; } } getPostTitles() .then((postTitles) => console.log(postTitles)) .catch(err => console.log(err));
解决方案
嘿,我来帮你搞定这个问题!你当前的选择器.md ul li会匹配页面中所有带有md类的div下的所有列表项,这就是为什么会同时抓到info和relatedReddits的内容。我们可以通过更精准的选择器来只定位guidelines板块的列表:
方法1:基于板块标题精准定位(推荐)
页面里guidelines板块的标题是<h3>guidelines</h3>,它紧邻着包含列表的md类div,我们可以用Cheerio的兄弟选择器+来定位这个div,再抓取里面的列表项:
把原来的这段代码:
$('.md ul li').each((idx, el) => { const guideline = $(el).text(); guidelines.push(guideline); });
替换成:
$('h3:contains("guidelines") + .md ul li').each((idx, el) => { const guideline = $(el).text().trim(); // 顺便去掉多余的空白字符 guidelines.push(guideline); });
这种方法的好处是即使页面右侧栏的板块顺序发生变化,只要标题不变,就能精准抓到目标内容,稳定性更强。
方法2:基于位置定位
如果确定guidelines是右侧栏的第一个md类板块,也可以用:first-of-type选择器来筛选第一个mddiv下的列表:
替换成:
$('.side .md:first-of-type ul li').each((idx, el) => { const guideline = $(el).text().trim(); guidelines.push(guideline); });
这个方法更简洁,但依赖页面板块的顺序,如果后续Reddit调整右侧栏顺序,可能会失效。
修改后运行代码,你就只会得到guidelines板块下的所有项目符号啦!
内容的提问来源于stack exchange,提问作者TanDev
相关产品推荐
相关产品推荐

