第一次爬虫

准备工作
首先下载Node.js以及VSCode这两个软件
找到电脑里的cmd命令行
然后还需要下载一些安装包,如request,cheerio,mysql等等
接下来就可以开始快乐地 爬虫了

初次接触
刚开始因为完全不懂,就从万能地hello world入手,让自己对Node.js有所了解

var foo="helloworld"

console.log("foo的值是:",foo)

爬虫任务
在这里插入图片描述
在正式开始之前,有一个开胃菜

var myRequest=require('request')
var myCheerio=require('cheerio')
var myURL='http://www.ecnu.edu.cn/e5/bc/c1950a255420/page.htm'

function request(url,callback){
    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())
    // html页面title的信息
    console.log('title:'+$('title').text())
    // html页面的摘要的信息
    // console.log('description:'+$('meta[name="description"]').eq(0).attr("content"))  
})

有一说一,搞得还有模有样。。
在这里插入图片描述
但接下来有我崩溃的了,呜~~

require
通过require引入各种包,以方便功能地实现
request:发送http请求;cheerio:获取html内容;
iconv-lite:编码转换;date-utils
(ps.此处还发生了一个小插曲,最后快要好的时候,死活找不到哪儿有问题,最后发现自己把date写成了data了,傻不啦叽的~~)

var fs=require('fs')
var myRequest=require('request') // 发http请求
var myCheerio=require('cheerio') // 获取html的内容
var myIconv=require('iconv-lite') // 编码转换GB2312到UTF-8
require('date-utils') // 为了解析日期的方便

获取URL
URL,全称uniform resource locator,是因特网的万维网服务程序上用于指定信息位置的表示方法;
其格式一般为“协议名 + 主机名/IP地址及其端口 + 文件路径”
所以我们需要获取网址(小声bb:我也不知道为什么要定义两个。。)

var source_name='中国新闻网'
var domain='http://www.chinanews.com/'
var myEncoding='utf-8'
var seedURL='http://www.chinanews.com/'

定义新闻元素的读取方式

var seedURL_format="$('a')" //把所有链接取出来
var keywords_format="$('meta[name=\"ketwords\"]').eq(0).attr(\"content\")"
var title_format="$('title').text()"
var date_format="$('#pubtime_baidu').text()"
var author_format="$('#editor_baidu').text()"
var content_format="$('.left_zw').text()"
var desc_format="$('meta[name=\"description\"]').eq(0).attr(\"content\")"
var source_format="$('#source_baidu').text()"
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}日)/

正则表达式
正则表达式描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
一些常见的例子
. 可以表示所有字符,但不包括回车换行;
[ ] 方括号里面是‘或’的关系;表示任意小写字母;[A-Z]表示任意大写字母;[A-z]表示任意字母;[A-z0-9]表示所有的字母和数字
+:表示一个及其以上相当于{1,};*:表示0个及以上相当于{0,};?:表示0或1个相当于{0,1};
如一个手机号的正则表达式:var phoneReg=/^1[3-9][0-9]{9}$/;

防止网站屏蔽我的爬虫

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,
        headers:headers,
        timeout:10000
    }
    myRequest(options,callback);
}

读取种子页面,解析所有的a链接
try{}catch(err){}
try:检查是否又错误的代码块;catch:如果try语句发生错误执行的代码块它执行。

读取种子页面

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

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

遍历种子页面里所有的链接

seedurl_news.each(function(i,e){ 
        var myURL=""
        try{
            // 得到具体新闻url
            var href=""
            href=$(e).attr("href")
            if (href.toLowerCase().indexOf('http://')>=0){
                myURL=href //http://开头的(绝对路径)
            }
            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的正则表达式
            // 类似continue
        }
        // console,length(myURL)
        newsGet(myURL) //读取新闻页面
    })
})

** 读取具体的新闻页面,构造一个空的fetch对象用于存储数据**

function newsGet(myURL) { //读取新闻页面
    var options={
        url:myURL,
        encoding:null,
        timeout:10000
    }
    myRequest(options,function(err,res,body){ //读取新闻页面
        try{
            var html_news=myIconv.decode(body,myEncoding) //用iconv转换编码
            // console.log(html_news)
            var $=myCheerio.load(html_news,{decodeEntities: true}) //准备用Cheerio解析html_news
            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()

        // 读取新闻页面中的元素并保存到fetch对象里
        if (keywords_format==""){
            fetch.keywords=source_name //eval(keywords_format)
        }
        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)
        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 //作者
        }
        else{
            fetch.author=eval(author_format)
        }
        if (content_format=="")
        {
            fetch.content="" //内容
        }
        else{
            fetch.content=eval(content_format).replace("\r\n"+fetch.author,"")
        }
        if (source_format==""){
            fetch.source=fetch.source_name //来源
        }
        else{
            fetch.source=eval(source_format).replace("\r\n","")
        }
        if (desc_format==""){
            fetch.desc=fetch.title //摘要
        }
        else{
            fetch.desc=eval(desc_format).replace("\r\n","")
        }
        // 将fetch对象保存在文件中
        var filename=source_name+"_"+(new Date()).toFormat("YYYY-MM-DD")+"_"+myURL.substr(myURL.lastIndexOf('/')+1)+".json"
        // 存储json
        fs.writeFileSync(filename,JSON.stringify(fetch))
    })
}

**小菜鸟遇到的一下憨憨问题 **
看着老师的视频,照着敲了一遍代码,一运行,瞬间傻眼了,这都是些啥,
所以接下来开始了我的暴风修改计划~~
在这里插入图片描述
在这里插入图片描述

噔噔噔!!!第一次修改结束,报错倒是没了,它直接不给我输出了。。。晕~
在这里插入图片描述
靠我自己这辈子别想改好了,悄咪咪得到询问了自己的大佬同学,得知代码还是出现了小问题,自己的request的函数都没有用到options。。。当当当当,新鲜代码出炉
在这里插入图片描述
尽管还是有点小问题没有解决,但至少没有出现乱码了,可喜可贺啊 ,唉~😔
在这里插入图片描述

这样一个爬虫实验的代码就结束了,接下来我们来尝试升级一下

未完待续~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值