이번에는 nodeJs 크롤러를 사용하는 단계에 대해 자세히 설명하겠습니다. nodeJs 크롤러를 사용할 때 주의사항은 무엇인가요?
Background
최근에는 예전에 봤던 nodeJs 관련 내용을 복습하고, 크롤링 과정에서 몇 가지 문제점을 발견해서 메모용으로 기록해두려고 합니다.
Dependency
크롤링된 콘텐츠를 처리하기 위해 인터넷에서 널리 사용되는 Cherio 라이브러리를 사용하며, 요청을 처리하기 위해 superagent를 사용하고, 로그를 기록하기 위해 log4js를 사용합니다.
로그 구성
말할 것도 없이 바로 코드로 들어가자:
const log4js = require('log4js'); log4js.configure({ appenders: { cheese: { type: 'dateFile', filename: 'cheese.log', pattern: '-yyyy-MM-dd.log', // 包含模型 alwaysIncludePattern: true, maxLogSize: 1024, backups: 3 } }, categories: { default: { appenders: ['cheese'], level: 'info' } } }); const logger = log4js.getLogger('cheese'); logger.level = 'INFO'; module.exports = logger;
위는 로거 객체를 직접 내보내고, 비즈니스 파일에서 logger.info() 및 기타 함수를 직접 호출하여 로그 정보를 추가한다. , 매일 생성되는 로그입니다. 인터넷에는 관련 정보가 많이 있습니다.
콘텐츠 및 프로세스를 크롤링합니다.
superagent.get(cityItemUrl).end((err, res) => { if (err) { return console.error(err); } const $ = cheerio.load(res.text); // 解析当前页面,获取当前页面的城市链接地址 const cityInfoEle = $('.newslist1 li a'); cityInfoEle.each((idx, element) => { const $element = $(element); const sceneURL = $element.attr('href'); // 页面地址 const sceneName = $element.attr('title'); // 城市名称 if (!sceneName) { return; } logger.info(`当前解析到的目的地是: ${sceneName}, 对应的地址为: ${sceneURL}`); getDesInfos(sceneURL, sceneName); // 获取城市详细信息 ep.after('getDirInfoComplete', cityInfoEle.length, (dirInfos) => { const content = JSON.parse(fs.readFileSync(path.join(dirname, './imgs.json'))); dirInfos.forEach((element) => { logger.info(`本条数据为:${JSON.stringify(element)}`); Object.assign(content, element); }); fs.writeFileSync(path.join(dirname, './imgs.json'), JSON.stringify(content)); }); }); });
슈퍼에이전트를 사용하여 페이지를 요청합니다. 요청이 성공한 후 Cherio를 사용하여 페이지 콘텐츠를 로드한 다음 Jquery와 유사한 일치 규칙을 사용하여 대상 리소스를 찾습니다.
여러 리소스가 로드되고, 이벤트 프록시를 사용하여 이벤트를 프록시하고, 하나의 리소스를 처리하고 하나의 이벤트를 처벌하고, 모든 이벤트가 트리거된 후 데이터를 처리합니다.
위는 가장 기본적인 크롤러입니다. 다음은 문제를 일으킬 수 있거나 특별한 주의가 필요한 영역입니다. . .
로컬 파일 읽기 및 쓰기
폴더 만들기
function mkdirSync(dirname) { if (fs.existsSync(dirname)) { return true; } if (mkdirSync(path.dirname(dirname))) { fs.mkdirSync(dirname); return true; } return false; }
파일 읽기 및 쓰기
const content = JSON.parse(fs.readFileSync(path.join(dirname, './dir.json'))); dirInfos.forEach((element) => { logger.info(`本条数据为:${JSON.stringify(element)}`); Object.assign(content, element); }); fs.writeFileSync(path.join(dirname, './dir.json'), JSON.stringify(content));
리소스를 일괄 다운로드
다운로드한 리소스에는 사진, 오디오 등이 포함될 수 있습니다.
백파이프를 사용하여 비동기 동시성을 처리합니다. 리소스를 다운로드하고 스트림을 사용하여 파일 쓰기를 완료하려면
const Bagpipe = require('bagpipe'); const bagpipe = new Bagpipe(10); bagpipe.push(downloadImage, url, dstpath, (err, data) => { if (err) { console.log(err); return; } console.log(`[${dstpath}]: ${data}`); });
를 참조하세요.
function downloadImage(src, dest, callback) { request.head(src, (err, res, body) => { if (src && src.indexOf('http') > -1 || src.indexOf('https') > -1) { request(src).pipe(fs.createWriteStream(dest)).on('close', () => { callback(null, dest); }); } }); }
Encoding
때때로cherio.load를 사용하여 직접 처리한 웹 콘텐츠가 파일 작성 후 인코딩된 텍스트로 발견되는 경우가 있습니다.
const $ = cheerio.load(buf, { decodeEntities: false });
,
ps: 인코딩 라이브러리 및 iconv-lite를 통해 인코딩을 비활성화할 수 있습니다. UTF-8로 인코딩된 문자를 중국어로 변환할 수 없습니다. API에 익숙하지 않을 수 있으므로 나중에 주의하시기 바랍니다.
마지막으로 모든 DOM 태그와 일치하는 정규식을 첨부하세요
const reg = /<.*?>/g;
이 기사의 사례를 읽으신 후 방법을 마스터하셨다고 믿습니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!
추천 도서:
jQuery 클래스 이름 선택기(.class) 사용 방법에 대한 자세한 설명
js 캡슐화된 Ajax 함수 함수를 구현하는 단계에 대한 자세한 설명
위 내용은 nodeJs 크롤러 사용 단계에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!