【Mac】从0开始用node.js制作爬取结果的查询网站

本文介绍了在Mac上使用Node.js从零开始制作新闻爬虫和查询网站的过程,涵盖爬虫原理、JavaScript语法、网络元素提取、正则表达式、MySQL数据库操作、前端和后端知识。作者分享了遇到的挑战,如在Mac上安装MySQL和使用express脚手架的问题,并提供了部分源代码示例。
摘要由CSDN通过智能技术生成

实验要求

新闻爬虫及爬取结果的查询网站

核心需求:
1、选取3-5个代表性的新闻网站(比如新浪新闻、网易新闻等,或者某个垂直领域权威性的网站比如经济领域的雪球财经、东方财富等,或者体育领域的腾讯体育、虎扑体育等等)建立爬虫,针对不同网站的新闻页面进行分析,爬取出编码、标题、作者、时间、关键词、摘要、内容、来源等结构化信息,存储在数据库中。
2、建立网站提供对爬取内容的分项全文搜索,给出所查关键词的时间热度分析。

技术要求:
1、必须采用Node.JS实现网络爬虫
2、必须采用Node.JS实现查询网站后端,HTML+JS实现前端(尽量不要使用任何前后端框架)

刚接触半年编程的小白在第一节课看到实验要求时是心态崩溃的,还好经过一段时间的学习与不断摸索,有了一些浅显的理解,希望可以帮助到大家
PS:发现用Mac完成一些操作与Windows不同,有一些天坑。希望此篇可以帮助大家避坑。

实验结果展示

1.中国新闻网试运行
中国新闻网的查询建表显示
2.自己爬虫——新浪新闻网
新浪新闻
3.爬取东方财富网东方财富网
4.爬取中国证券网(这里出现了一些问题待解决)(MYSQL出现问题待解决,现只能暂时存在本地)
在这里插入图片描述

简单了解实验项目所需知识

开始爬虫之前(心理建设无数次之后
通过仔细、认真、完整地研究了一遍老师的PPT,了解到从0入手node.js爬虫大概需要以下知识。

1 爬虫原理

1 、首先我们选定网站查看源代码,获取我们想要的子网页的URL

  • 通过request请求,cheerio解析,each遍历
    (cheerio模块囊括了对html页面的解析,分块,提取等多个功能,是实现爬虫功能最主要的工具。)
    (为了实现爬虫功能,通常要在代码头部用require函数引入request、cheerio、iconv-lite和fs四个模块,其中fs是node.js内置的,其他三个需要安装)

2 、搜索出我们子网页页面中我们需要的信息:标题、正文关键字等

  • 搜索后,写入代码,爬虫功能通过request请求,cheerio解析实现

3 、将这些我们需要的信息保存下来,通过各种形式访问到这种信息

  • 建立fetch(文件对象),输入文件信息,fs /mysql模块写入(即本地保存或数据库保存)

2 JavaScript语法

主要介绍一些基本语法(由于js要用JavaScript编写,需要理解一些基本语法,其他更多的语法就不多谢啦,要看专门的介绍👀)

  • JavaScript 使用关键字 var 来定义变量, 使用等号来为变量赋值
var x, length;
x = 5;
length = 6;
  • JavaScript 数据类型
    JavaScript 有多种数据类型:数字,字符串,数组,对象等等:
var length = 16;                                  // Number 通过数字字面量赋值
var points = x * 10;                              // Number 通过表达式字面量赋值
var lastName = "Johnson";                         // String 通过字符串字面量赋值
var cars = ["Saab", "Volvo", "BMW"];              // Array  通过数组字面量赋值
var person = {
   firstName:"John", lastName:"Doe"};  // Object 通过对象字面量赋值
  • JavaScript 函数
    JavaScript 语句可以写在函数内,函数可以重复引用:
    引用一个函数 = 调用函数(执行函数内的语句)。
function myFunction(a, b) {
   
    return a * b;                                // 返回 a 乘以 b 的结果
}

3 网络元素的提取

  • 观察老师给的源码的这个部分
    这里就是选择的网页及要爬取的网络元素,对于不同网页我们该如何写这些元素呢
  • 下面以我爬取的新浪新闻网做解释
var source_name = "新浪新闻网";
var myEncoding = "utf-8";
var seedURL = 'https://news.sina.com.cn/china/';



//定义新闻页面内具体元素的读取方式
var seedURL_format = "$('a')";

/*<meta name="keywords" content="新冠肺炎,新型冠状病毒肺炎疫情" />*/
var keywords_format = "$('meta[name=\"keywords\"]').eq(0).attr(\"content\")";

var title_format = "$('title').text()";

/*<meta property="article:published_time" content="2021-04-25T09:41:41+08:00" /> */
var date_format = "$('meta[property=\"article:published_time\"]').eq(0).attr(\"content\")";   //从指定标签的第0个位置,即首位,开始取出content内容,上同


/*<p class="show_author">责任编辑:张迪 </p> */
var author_format = "$('.show_author').text()"; //class用'.'号标识符取出


/*<div class="article-content clearfix" id='article_content'> */
var content_format = "$('.article').text()";

/*<meta name="description" content="原标25最简……施计划免疫工作至今," /> */
var desc_format = " $('meta[name=\"description\"]').eq(0).attr(\"content\")";

/*class="source" data-sudaclick="content_media_p" rel="nofollow">北京日报 */
var source_format = "$('.source').text()";

var url_reg = /\/((\d{4})-(\d{2})-(\d{2}))\/(doc-(\w{15})).shtml/;    //正则表达式筛选不同的部分
var regExp = /((\d{
   4})-(\d{
   2})-(\d{
   2}))/    //筛去无用信息

如图查找

  • 首先,更改网页名字与网页的URL;
  • 第二,注释中为查看网页源码后找到所需爬取元素所在的位置
    (Mac在查看源代码后按住Fn 出现F12键搜索想得到的元素)
  • 最后,可以直接定义变量提取网络元素(书写规则可找规律,如在class中、meta中等等)

4 正则表达式

下图为老师给出“中国新闻网”的正则表达式
(现在也觉得真的好难)

var url_reg = /\/(\d{4})\/(\d{2})-(\d{2})\/(\d{7}).shtml/;
var regExp = /((\d{4}|\d{2})(\-|\/|\.)\d{1,2}\3\d{1,2})|(\d{4}年\d{1,2}月\d{1,2}日)/

我先在网上查了菜鸟教程,发现以我的耐心和脑力看一半就心力交瘁😇,于是还是去B站找了视频教学,都贴上链接,希望有助于大家。
B站视频:正则表达式入门
菜鸟教程正则表达式语法|菜鸟教程
写完之后可以先在网页上测试一遍是否匹配
测试页面:测试网址

当然,完整掌握正则表达式还需要更多学习,建议参考犀牛书中介绍

5 其他有关MySQL数据库

最广泛的开源数据库MySQL
可以实现创建表、插入表、删除表等功能

Mac版本安装好后的界面

这部对我来说是最困难的,因为网上的。大部分教程针对Windows,而Mac的MySQL又一直在出现无法预料的问题,解决和未解决的问题都将在「问题」部分解释。

6 前端方面

HTML基础

内容包括:(HTML简介与历史版本、常用开发软件、常见标签与属性、
表格与表单、标签规范与标签语义化、实战:网页结构布局)

CSS基础
内容包括:(css简介与基本语法、常见的各种样式属性、CSS选择器与标签类型)

目标:HTML+CSS开发网页

7 后端方面

本项目主要使用 SQL 语言

  • 数据库方面要精通mysql的sql语法;大数据场景主要掌握Hive SQL(Impala和Spark SQL等均在兼容Hive SQL)
  • 核心知识点区分DDL和DML经典查询语句主要结构表连接(内连接,左外连接,右外连接,全连接)函数(普通函数,聚合函数)索引分区

完整爬取一个网站的过程

项目示例1

  1. 先在终端安装cheerio与request包以实现功能
npm install cheerio

在终端输入即可

npm install request
  1. 最简单的代码示例
    (我将老师代码中学校网站改为了其他网站做了一下尝试)
    在终端中运行
var myRequest = require('request')
var myCheerio = require('cheerio')
// var myURL = 'https://www.ecnu.edu.cn/e5/bc/c1950a255420/page.htm'
var myURL = 'https://www.nogizaka46.com/'
function request(url, callback) {
   //request module fetching url
    var options = {
   
        url: url,  encoding: null, headers: null
    }
    myRequest(options, callback)
}
request(myURL, function (err, res, body) {
   
    var html = body;  
    var $ = myCheerio.load(html, {
    decodeEntities: false });
    console.log($.html());        
    //console.log("title: " + $('title').text());     
    //console.log("description: " + $('meta[name="description"]').eq(0).attr("content"));
})

分析:
1:引入Cheerio包,Request包;
2:把要爬取的URL定义在myURL这个变量;
3:创建request函数;
4:用console.log把这个html打印出来。

  1. 其他可用函数
var schedule = require('node-schedule')  //设置定时爬虫
var myIconv = require(‘iconv-lite’)  //编码转换 GB2312到UTF-8
var fs = require(‘fs’);  //保存到本地文件
var mysql = require(‘mysql’);  //保存到mysql数据库

可引入的包

npm install elasticsearch  //可以用elasticsearch构建爬取数据的索引

  • 运行结果界面
    终端的显示
    以上,一个最简单的爬虫就完成了!

项目二示例

  • 如何爬取一个新闻网站种子页面中所包含的各新闻的信息。
    (以我更改后爬取的东方财富网为例)

东方财富网主页面

点开一个页面,查看源代码,找到想要爬取的元素,按照上述方法写入代码
代码如下

var source_name = "东方财富";
var myEncoding = "utf-8";
var seedURL = 'https://www.eastmoney.com/';



var seedURL_format = "$('a')";
// <meta name="keywords" content="机构论市,调仓,机会,共识,八大,反弹,牛市,居民,资产配置,沪指" />
var keywords_format = " $('meta[name=\"keywords\"]').eq(0).attr(\"content\")";

var title_format = "$('title').text()";
//    <div class="time">2021年04月25日 19:04</div>
var date_format = "$('.time').text()";
//<p class="res-edit">
var author_format = "$('.res-edit').text()";
//<div class="mainFrame">
var content_format = "$('.mainFrame').text()";
//<meta name="description" content="
var desc_format = " $('meta[name=\"description\"]').eq(0).attr(\"content\")";
//<div class="source data-source" data-source="东方财富研究中
var source_format = "$('.data-source').text()";



var url_reg = /\/(\d{4})(\d{2})(\d{2})(\d{10}).html/;
var regExp = /((\d{4}|\d{2})(\-|\/|\.)\d{1,2}\3\d{1,2})|(\d{4}年\d{1,2}月\d{1,2}日)/




var fs = require('fs');
var myRequest = require('request')
var myCheerio = require('cheerio')
var myIconv = require('iconv-lite')
require('date-utils');

//防止网站屏蔽我们的爬虫
var headers = {
   
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36'
}

//request模块异步fetch url
function request(url, callback) {
   
    var options = {
   
        url: url,
        encoding: null,
        //proxy: 'http://x.x.x.x:8080',
        headers: headers,
        timeout: 10000 //
    }
    myRequest(options, callback)
}

request(seedURL, function(err, res, body) {
    //读取种子页面
    // try {
   
    //用iconv转换编码
    var html = myIconv.decode(body, myEncoding);
    //console.log(html);
    //准备用cheerio解析html
    var $ = myCheerio.load(html, {
    decodeEntities: true });
    // } catch (e) { console.log('读种子页面并转码出错:' + e) };

    var seedurl_news;

    try {
   
        seedurl_news = eval(seedURL_format);
        //console.log(seedurl_news);
    } catch (e) {
    console.log('url列表所处的html块识别出错:' + e) };

    seedurl_news.each(function(i, e) {
    //遍历种子页面里所有的a链接
        var myURL = "";
        try {
   
            //得到具体新闻url
            var href = "";
            href = $(e).attr("href");
            if (typeof(href) == "undefined") {
     // 有些网页地址undefined
                return true;
            }
            if (href.toLowerCase().indexOf('http://') >= 0 || href.toLowerCase().indexOf('https://') >= 0) myURL = href; //http://开头的或者https://开头
            else if (href.startsWith('//')) myURL = 'http:' + href; 开头的
            else myURL = seedURL.substr(0, seedURL.lastIndexOf('/') + 1) + href; //其他

        } catch (e) {
    console.log('识别种子页面中的新闻链接出错:' + e) }

        if (!url_reg.test(myURL)) return; //检验是否符合新闻url的正则表达式
        //console.log(myURL);
        newsGet(myURL); //读取新闻页面
    });
});

function newsGet(myURL) {
    //读取新闻页面
    request(myURL, function(err, res, body) {
    //读取新闻页面
        //try {
   
        var html_news = myIconv.decode(body, myEncoding); //用iconv转换编码
        //console.log(html_news);
        //准备用cheerio解析html_news
        var $ = myCheerio.load(html_news, {
    decodeEntities: true });
        myhtml = html_news;
        //} catch (e) {    console.log('读新闻页面并转码出错:' + e);};

        console.log("转码读取成功:" + myURL);
        //动态执行format字符串,构建json对象准备写入文件或数据库
        var fetch = {
   };
        fetch.title = "";
        fetch.content = "";
        fetch.publish_date = (new Date()).toFormat("YYYY-MM-DD");
        //fetch.html = myhtml;
        fetch.url = myURL;
        fetch.source_name = source_name;
        fetch.source_encoding = myEncoding; //编码
        fetch.crawltime = new Date();

        if (keywords_format == "") fetch.keywords = source_name; // eval(keywords_format);  //没有关键词就用sourcename
        else fetch.keywords = eval(keywords_format);

        if (title_format == "") fetch.title = ""
        else fetch.title = eval(title_format); //标题

        if (date_format != "") fetch.publish_date = eval(date_format); //刊登日期   
        console.log('date: ' + fetch.publish_date);
        console.log(myURL);
        fetch.publish_date = regExp.exec(fetch.publish_date)[0];
        fetch.publish_date = fetch.publish_date.replace('年', '-')
        fetch.publish_date = fetch.publish_date.replace('月', '-')
        fetch.publish_date = fetch.publish_date.replace('日', '')
        fetch.publish_date = new Date(fetch.publish_date).toFormat("YYYY-MM-DD");

        if (author_format == "") fetch.author = source_name; //eval(author_format);  //作者
        else fetch.author = eval(author_format
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值