node.js,网络爬虫

文章目录

前言

一、网站演示

二、网站构造过程

1.爬取数据

2.网站构建

总结



前言

这是我首次接触和使用javascript语言,也是我制作的第一个网站,虽然在制作的过程中也遇到了许多问题。

接下来先演示一下我的网站,然后逐步分析网站制作过程。


一、网站演示

因为本人对军事相关的讯息和新闻较为感兴趣,所以本次项目我做制作的网站是一个军事类新闻搜索网站。

网站主页如下:

网站支持的功能全部可以通过主页直接到达,除了支持根据输入的信息单项查找,还支持多种复合查找,从而增大了网站查找的准确率;对于搜索得到的结果,会采用时间顺序排列,便于使用者第一时间获取到最新的新闻;网站还提供了时间热度搜索,可以绘制出所搜索的词近日在新闻中出现的次数,从而直观地看出这个搜索词的热度变化情况。通过导航栏我们可以看到网站的简介:

接下来演示一下网站的核心搜素功能。

单项搜索:以标题搜索为例,其它的单项搜索都是类似的:

标题搜索的主界面如下,有一个按键可以回到主页。在输入框中输入关键字后点击“查询”即可获得结果。这里我们以“中国”为例,获取所有标题带“中国”的军事新闻,结果如下:

网站会呈现所有标题带“中国”字样的新闻的相关信息,使用者可以直观地获取到自己想要的信息,或是通过原始url去访问新闻页面。

复合搜索:这里以新闻来源+时间复合搜索为例,其它的复合搜索是相似的。

在输入框内输入我们想要的新闻来源和新闻发布时间,就可以搜索到相应的新闻信息。这里我们以“网易军事”和“2022-07-19”为例,结果如下:

 时间热度搜索:输入任意的关键字,网站可以立即绘制出一幅时间热度图,显示今日该关键字的出现频率情况,我们以“乌克兰”为例。

二、网站构造过程

1.爬取数据

我们的新闻数据是从网易军事、新浪军事、凤凰军事以及环球军事网上爬取并储存到本地的数据库中的。因此我们有四段爬虫代码,分别负责爬取不同的网站,但这四段代码是相似的,它们的主要不同点在于数据爬取方式不同(因网站格式而异)。我们这里以爬取网易军事的爬虫为例,对爬虫代码进行说明。

先使用命令创建一个数据库crawl,并在这个数据库中创建表fetches用于储存数据,fetches的格式如下:

自定义一个mysql.js文件,它负责向本地mysql库插入或是查询数据。

var mysql = require("mysql");
var pool = mysql.createPool({host: '127.0.0.1',user: 'root',password: 'root',database: 'crawl',port: '3306'
});
var query = function(sql, sqlparam, callback) {pool.getConnection(function(err, conn) {if (err) {console.log("数据库连接失败")callback(err, null, null);} else {try{conn.query(sql, sqlparam, function(qerr, vals, fields) {conn.release(); //释放连接 callback(qerr, vals, fields); //事件驱动回调 });}catch(e){console.log("该数据已经获取")}}});
};
var query_noparam = function(sql, callback) {pool.getConnection(function(err, conn) {if (err) {console.log("数据库连接失败")callback(err, null, null);} else {conn.query(sql, function(qerr, vals, fields) {conn.release(); //释放连接 callback(qerr, vals, fields); //事件驱动回调 });}});
};
exports.query = query;
exports.query_noparam = query_noparam;

对于爬虫代码,第一步是引入各种库,并定义网站url以及网站相关信息:

///网易军事
var fs = require('fs');
var myRequest = require('request');
var myCheerio = require('cheerio');
var myIconv = require('iconv-lite');
require('date-utils');
var mysql = require('./mysql.js');var source_name = "网易军事";
var domain = 'https://war.163.com/';
var myEncoding = "utf-8";
var seedURL = 'https://war.163.com/';

第二步是定义数据读取方式,这里我们选择使用Jquery来获取网站数据:

var seedURL_format = "$('a')";
var keywords_format = "$('meta[name=\"keywords\"]').eq(0).attr(\"content\")";
var title_format = "$('.post_title').text()";
var date_format = "$('.post_info').text()";
var author_format = "$('meta[name=\"author\"]').eq(0).attr(\"content\")";
var content_format = "$('.post_body').text()";
var url_reg = /\/article\//;

该部分的读取方式会因网站而异,不同网站储存数据的方式有所不同,需要编写不同的读取方式,以keywords为例,检查网易军事的源代码,获取读取keywords的路径如下:

然后模拟浏览器请求,防止我们被反爬:

//防止网站屏蔽我们的爬虫
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)
};

第四步是读取种子网页,从中获取所有新闻的url:

seedget();
function seedget() {request(seedURL, function(err, res, body) { //读取种子页面// try {//用iconv转换编码var html = myIconv.decode(body, myEncoding);//console.log(html);//准备用cheerio解析htmlvar $ = myCheerio.load(html, { decodeEntities: true });// } 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) { //遍历种子页面里所有的a链接var myURL = "";try {//得到具体新闻urlvar href = "";href = $(e).attr("href");if (href == undefined) return;if (href.toLowerCase().indexOf('http://') >= 0) myURL = href; //http://开头的else if (href.startsWith('//')) myURL = 'http:' + href; 开头的else myURL = href; //其他} catch (e) { console.log('识别种子页面中的新闻链接出错:' + e) }if (!url_reg.test(myURL)) return; //检验是否符合新闻url的正则表达式//console.log(myURL);var fetch_url_Sql = 'select url from fetches where url=?';var fetch_url_Sql_Params = [myURL];mysql.query(fetch_url_Sql, fetch_url_Sql_Params, function(qerr, vals, fields) {if (vals.length > 0) {console.log('URL duplicate!')} else newsGet(myURL); //读取新闻页面});});});
};

最后一步是在刚刚获取到的子url中,获取到每条新闻的相关信息:

function newsGet(myURL) { //读取新闻页面request(myURL, function(err, res, body) { //读取新闻页面if (body == undefined) return;//try {var html_news = myIconv.decode(body, myEncoding); //用iconv转换编码//console.log(html_news);//准备用cheerio解析html_newsvar $ = myCheerio.load(html_news, { decodeEntities: true });myhtml = html_news;//} catch (e) {    console.log('读新闻页面并转码出错:' + e);};console.log("转码读取成功:" + myURL);//动态执行format字符串,构建json对象准备写入文件或数据库console.log()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);  //没有关键词就用sourcenameelse 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(fetch.keywords);console.log(fetch.title);if (fetch.publish_date.length != 0){fetch.publish_date = fetch.publish_date.trim();fetch.publish_date = fetch.publish_date.substring(0,10);console.log(fetch.publish_date)if (author_format == "") fetch.author = source_name; //eval(author_format);  //作者else fetch.author = eval(author_format);console.log(fetch.author);if (content_format == "") fetch.content = "";else fetch.content = eval(content_format).replace("\r\n" + fetch.author, ""); //内容,是否要去掉作者信息自行决定console.log(fetch.content);// var filename = source_name + "_" + (new Date()).toFormat("YYYY-MM-DD") +//     "_" + myURL.substr(myURL.lastIndexOf('/') + 1) + ".json";// 存储json// fs.writeFileSync(filename, JSON.stringify(fetch));var fetchAddSql = 'INSERT INTO fetches(url,source_name,source_encoding,title,' +'keywords,author,publish_date,crawltime,content) VALUES(?,?,?,?,?,?,?,?,?)';var fetchAddSql_Params = [fetch.url, fetch.source_name, fetch.source_encoding,fetch.title, fetch.keywords, fetch.author, fetch.publish_date,fetch.crawltime.toFormat("YYYY-MM-DD HH24:MI:SS"), fetch.content];//执行sql,数据库中fetch表里的url属性是unique的,不会把重复的url内容写入数据库mysql.query(fetchAddSql, fetchAddSql_Params, function(qerr, vals, fields) {if (qerr) {console.log(qerr);}}); //mysql写入}});
}

至此,我们已经成功地将网易军事的新闻全部读取并保存到了我们的数据库中。

对于其它的几个网站,我们只需根据每个网站的数据读取路径,稍微改写一下这段代码,便也可以轻松地获取到网站数据

2.网站构建

我们选择使用express脚手架来完成整个项目的搭建。

对于网站框架的主要思路是,先构建一个主页面,上面会有多个按钮,每个按钮通向一个子页面,实现某个具体的功能;再加上一个导航栏,让用户可以通过导航栏获取网站简介。对于简介页面,只需简单的呈现介绍文字即可;而对于其它子页面,我们要让用户可以输入关键字,然后点击搜索按钮从而呈现出对应的结构;另外每个主页面还需要加上一个按钮,以方便用户返回主页面。

所有html文件均保存在express项目的public文件下,对应的图片背景保存在public/images文件下。

我们首先修改bin文件下的www文件,使得项目监听的端口号为8081。

#!/usr/bin/env node/*** Module dependencies.*/var app = require('../app');
var debug = require('debug')('eps-1:server');
var http = require('http');/*** Get port from environment and store in Express.*/var port = normalizePort(process.env.PORT || '8081');
app.set('port', port);/*** Create HTTP server.*/var server = http.createServer(app);/*** Listen on provided port, on all network interfaces.*/server.listen(port);
server.on('error', onError);
server.on('listening', onListening);/*** Normalize a port into a number, string, or false.*/function normalizePort(val) {var port = parseInt(val, 10);if (isNaN(port)) {// named pipereturn val;}if (port >= 0) {// port numberreturn port;}return false;
}/*** Event listener for HTTP server "error" event.*/function onError(error) {if (error.syscall !== 'listen') {throw error;}var bind = typeof port === 'string'? 'Pipe ' + port: 'Port ' + port;// handle specific listen errors with friendly messagesswitch (error.code) {case 'EACCES':console.error(bind + ' requires elevated privileges');process.exit(1);break;case 'EADDRINUSE':console.error(bind + ' is already in use');process.exit(1);break;default:throw error;}
}/*** Event listener for HTTP server "listening" event.*/function onListening() {var addr = server.address();var bind = typeof addr === 'string'? 'pipe ' + addr: 'port ' + addr.port;debug('Listening on ' + bind);
}

接着我们编辑index.js文件,用来处理和响应各种请求。修改后的代码如下:

var express = require('express');
var router = express.Router();
var mysql = require('../mysql.js');/* GET home page. */
router.get('/', function(req, res, next) {res.render('index', { title: 'Express' });
});router.get('/searcht', function(request, response) {//标题搜索response.writeHead(200, { 'Content-Type': 'application/json' });var sql_search = "select url,source_name,title,keywords,author,publish_date from fetches where title like '%" +request.query.title + "%' order by publish_date desc";mysql.query(sql_search, function(err, result, fields) {response.write(JSON.stringify(result));response.end();});
});router.get('/searchs', function(request, response) {//来源搜索response.writeHead(200, { 'Content-Type': 'application/json' });var sql_search = "select url,source_name,title,keywords,author,publish_date from fetches where source_name like '%" +request.query.source_name + "%' order by publish_date desc";mysql.query(sql_search, function(err, result, fields) {response.write(JSON.stringify(result));response.end();});
});router.get('/searchk', function(request, response) {//关键词搜索response.writeHead(200, { 'Content-Type': 'application/json' });var sql_search = "select url,source_name,title,keywords,author,publish_date from fetches where keywords like '%" +request.query.keywords + "%' order by publish_date desc";mysql.query(sql_search, function(err, result, fields) {response.write(JSON.stringify(result));response.end();});
});router.get('/searchp', function(request, response) {//时间搜索response.writeHead(200, { 'Content-Type': 'application/json' });var sql_search = "select url,source_name,title,keywords,author from fetches where publish_date like '%" +request.query.publish_date + "%' order by publish_date desc";mysql.query(sql_search, function(err, result, fields) {response.write(JSON.stringify(result));response.end();});
});router.get('/searchts', function(request, response) {//标题+来源复合搜索response.writeHead(200, { 'Content-Type': 'application/json' });var sql_search = "select url,source_name,title,keywords,author,publish_date from fetches where title like '%" +request.query.title + "%' and source_name like '%" +request.query.source_name + "%' order by publish_date desc";mysql.query(sql_search, function(err, result, fields) {response.write(JSON.stringify(result));response.end();});
});router.get('/searchks', function(request, response) {//关键词+来源复合搜索response.writeHead(200, { 'Content-Type': 'application/json' });var sql_search = "select url,source_name,title,keywords,author,publish_date from fetches where keywords like '%" +request.query.keywords + "%' and source_name like '%" +request.query.source_name + "%' order by publish_date desc";mysql.query(sql_search, function(err, result, fields) {response.write(JSON.stringify(result));response.end();});
});router.get('/searchps', function(request, response) {//时间+来源复合搜索response.writeHead(200, { 'Content-Type': 'application/json' });var sql_search = "select url,source_name,title,keywords,author from fetches where publish_date like '%" +request.query.publish_date + "%' and source_name like '%" +request.query.source_name + "%' order by publish_date desc";mysql.query(sql_search, function(err, result, fields) {response.write(JSON.stringify(result));response.end();});
});module.exports = router;

准备工作进行完后,我们编写前端代码。首先编写主页面代码。

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>军事新闻搜索主页</title><style>#main {color:black;text-align:center;}p{font-size: 36px;}</style><link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script><script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body background="images/图片1.png"><div class="container" style="background-color: white;"><ul class="nav nav-pills nav-justified"><li class="nav-item"><a class="nav-link active" href="#">首页</a></li><li class="nav-item"><a class="nav-link" href="http://localhost:8081/intro.html">介绍</a></li></ul></div><div id="main"><br><br><br><br><br><p style="color: white;">欢迎浏览军事新闻搜索网!</p><b style="color: yellow;"> 单项查找: </b><a href="http://localhost:8081/web1.html"><button style="width: 110px;height: 40px;font-size: 15px;">标题搜索</button></a><a href="http://localhost:8081/web2.html"><button style="width: 110px;height: 40px;font-size: 15px;">来源搜索</button></a><a href="http://localhost:8081/web3.html"><button style="width: 110px;height: 40px;font-size: 15px;">关键词搜索</button></a><a href="http://localhost:8081/web7.html"><button style="width: 110px;height: 40px;font-size: 15px;">时间搜索</button></a><br><br><b style="color: yellow;"> 复合查找: </b><a href="http://localhost:8081/web5.html"><button style="width: 170px;height: 60px;font-size: 15px;">标题+来源复合搜索</button></a><a href="http://localhost:8081/web6.html"><button style="width: 170px;height: 60px;font-size: 15px;">关键词+来源复合搜索</button></a><a href="http://localhost:8081/web8.html"><button style="width: 170px;height: 60px;font-size: 15px;">来源+时间复合搜索</button></a><br><br><b style="color: yellow;"> 时间热度图: </b><a href="http://localhost:8081/web4.html"><button style="width: 110px;height: 40px;font-size: 15px;">时间热度搜索</button></a><br><br></div>
</body></html>

主页面包含了导航栏以浏览简介,以及多个按钮,点击它们进入子界面完成查询功能。

介绍页面代码如下:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>军事新闻搜索主页</title><style>#main {color:black;text-align:center;}p{font-size: 36px;}#introduction {width:350px;float:left;padding:10px;}</style><link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script><script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body background="images/图片1.png"><div class="container" style="background-color: white;"><ul class="nav nav-pills nav-justified"><li class="nav-item"><a class="nav-link" href="http://localhost:8081/main.html">首页</a></li><li class="nav-item"><a class="nav-link active" href="#">介绍</a></li></ul></div><div id="introduction"><p style=" color:white; font-size: 5; height: 300px; width: 900px;position: absolute; right: 460px; bottom: 500px;">简介:<br>本站包含来自网易军事,新浪军事,凤凰军事,以及环球军事网的最新新闻。可以通过标题搜索、来源搜索、关键词搜索以及新闻时间搜索等多种模式来获取您感兴趣的新闻,获取的新闻会按时间顺序呈现。<br><br>同时本站支持复合搜索,可同时使用多个字段进行搜索,更加准确。<br><br>提供了每个关键词的热度分析图,可以直观地看出一个热点近期的热度变化情况。<br><br>Tips:使用时间搜索时,需按照对应的时间格式输入。</p></div>
</body></html>

对于单项查找子页面,它们的结构是类似的,这里以标题单项查找为例:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>标题搜索</title><style>#search {color:black;text-align:center;}table,table tr th, table tr td { border:2px solid yellowgreen; }table { width: 1910px; min-height: 30px; line-height: 50px; text-align: center; border-collapse: collapse; color: yellow;}   </style><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<body background="images/图片4.png"><div id="search"><form><br> 请输入:<input type="text" name="title" style="width: 150px; height: 40px"/><input class="form-submit" type="button" value="查询" style="width: 60px;height: 40px;background-color: red;color: black;font-size: 20px;border-radius: 10px;"/></form><a href="http://localhost:8081/main.html"><button style="width: 110px;height: 40px;font-size: 15px;">返回主页</button></a></div><div class="cardLayout" style="margin: 10px 0px"><table width="100%" id="record"></table></div><script>$(document).ready(function() {$("input:button").click(function() {$.get('/searcht?title=' + $("input:text").val(), function(data) {var count = 0;$("#record").empty();$("#record").append('<tr class="cardLayout"><td>新闻链接</td><td>来源</td><td>标题</td><td>关键词</td><td>发布者</td><td>发布时间</td></tr>');for (let list of data) {let table = '<tr class="cardLayout"><td>';Object.values(list).forEach(element => {if (count < 5) {table += (element + '</td><td>');count += 1;}else {table += (element.slice(0,10) + '</td><td>');count = 0;}});$("#record").append(table + '</td></tr>');}});});});</script>
</body></html>

点击按钮以触发查询操作,并将查询的结果以表格的形式整齐地呈现在网页上。

对于复合查找,我们这里以标题+来源复合查找为例子,演示源代码:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>标题+来源复合搜索</title><style>#search {color:black;text-align:center;}table,table tr th, table tr td { border:2px solid yellowgreen; }table { width: 1910px; min-height: 30px; line-height: 50px; text-align: center; border-collapse: collapse; color: yellow;}   </style><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<body background="images/图片8.png"><div id="search"><form><br> 请输入标题:<input type="text" name="title" style="width: 150px; height: 40px" id = "title"/><br> 请输入来源:<input type="text" name="source_name" style="width: 150px; height: 40px" id = "source_name"/><br><input class="form-submit" type="button" value="查询" style="width: 60px;height: 40px;background-color: red;color: black;font-size: 20px;border-radius: 10px;"/></form><a href="http://localhost:8081/main.html"><button style="width: 110px;height: 40px;font-size: 15px;">返回主页</button></a></div><div class="cardLayout" style="margin: 10px 0px"><table width="100%" id="record"></table></div><script>$(document).ready(function() {$("input:button").click(function() {$.get('/searchts?title=' + $("#title").val() + '&source_name=' +$("#source_name").val(), function(data) {var count = 0;$("#record").empty();$("#record").append('<tr class="cardLayout"><td>新闻链接</td><td>来源</td><td>标题</td><td>关键词</td><td>发布者</td><td>发布时间</td></tr>');for (let list of data) {let table = '<tr class="cardLayout"><td>';Object.values(list).forEach(element => {if (count < 5) {table += (element + '</td><td>');count += 1;}else {table += (element.slice(0,10) + '</td><td>');count = 0;}});$("#record").append(table + '</td></tr>');}});});});</script>
</body></html>

输入两个关键词,进而使得查询的sql语句变成双重条件查询,获取符合两个要求的数据。其他复合查找的网页结构也是类似的。

时间热度搜索网页源代码如下:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>时间热度搜索</title><style>#search {color:black;text-align:center;}</style><script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@4.7.0/dist/echarts.min.js"></script>
</head>
<body background="images/图片7.png"><div id="search"><form><br> 请输入:<input type="text" name="title" style="width: 150px; height: 40px"/><input class="form-submit" type="button" value="查询" style="width: 60px;height: 40px;background-color: red;color: black;font-size: 20px;border-radius: 10px;"/></form><a href="http://localhost:8081/main.html"><button style="width: 110px;height: 40px;font-size: 15px;">返回主页</button></a></div><br><br><div id="graph" style="width: 1000px;height:667px; position: absolute; right: 450px; bottom: 100px; background-color: white;"></div><script type="text/javascript">$(document).ready(function() {$("input:button").click(function() {var dic = {};var x = [];var y = [];var i;$.get('/searcht?title=' + $("input:text").val(), function(data) {for (let list of data) {if (dic[list["publish_date"].slice(0,10)] == undefined) dic[list["publish_date"].slice(0,10)] = 1;else {dic[list["publish_date"].slice(0,10)] += 1;}}for (i in dic) {x.push(i);y.push(dic[i])}var myChart = echarts.init(document.getElementById('graph'));// 指定图表的配置项和数据var option = {title: {text: '时间热度图'},tooltip: {},legend: {data:['新闻数量']},xAxis: {data: x},yAxis: {},series: [{name: '新闻数量',type: 'bar',data: y}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);});});});</script>
</body></html>

在数据库中获取数据后,对数据进行简单处理,然后以图表形式呈现在网页上

至此,我们完成了网站的搭建。


总结

我们的网站除了满足了期末项目的全部要求外,还额外实现了对查询结果的分项排序(按发布时间排序),进而方便用户可以第一时间找到最新的新闻;也实现了对多个查询条件进行复合搜索;并将各个页面分离开,使得每个页面的功能单一化,便于维护和处理(这为我的开发过程节约了不少功夫)。由于我本次选择的新闻是军事方面的垂直领域新闻,所以新闻条目并不多,故没有加入分页系统。但如果新闻条目很大,每次搜索都可以搜索到较大数量的新闻时,引入分页功能就会十分必要。通过这个项目,我第一次实际上手使用js做项目,也是首次将数据库的使用带入项目中来,更是第一次接触到前端开发,学习前端开发的思维模式,收获颇丰。由于是第一次做网页,在开发过程中也遇到了许许多多的问题,但好在最后都得到了解决,做出了这个简陋但令我比较满意的网页(妈妈怎么会嫌弃自家儿子丑呢)。

希望几年后的我,再回头看这篇文章的时候,我的编码水平可以让我感叹道:“这写的什么xx玩意?”

WEB编程期末项目——我的第一个网站相关推荐

  1. web编程期中项目作业

    新闻爬虫与爬取结果的查询网站的实现 项目要求 一.爬虫部分 30分 1.完成最少一个目标网站(网站主题不限,不允许直接使用示例中的中国新闻网)的分析和爬虫设计. 2.爬取不少于100条数据(每条数据包 ...

  2. Web入门学习笔记1——建立第一个网站

    写在前面的话 参加工作后因为工作需要,博主暂时不搞计算机视觉和深度学习,转向Web开发了.这篇博客是学习Web开发的第一篇博客,记录下自己设计的第一个网站blateyang.github.io的过程, ...

  3. 期末项目——爬取王者荣耀网站

    目录 项目背景: 一.爬取英雄皮肤海报 1.准备: 2.代码实现 3.运行结果 二.导出英雄技能txt 1.思路分析 2.完整代码 3.运行结果 三.爬取英雄皮肤导入Excel 1.分析 2.完整代码 ...

  4. WEB前端期末大作业——关于酒店主题网站设计——高级酒店公寓网页(4页)

  5. Web前端期末大作业-在线手机商城网站设计(HTML+CSS+JS)

  6. Web前端期末大作业-网上订餐系统网站设计模板(HTML+CSS+JS)

  7. web前端期末大作业——响应式游戏介绍网站制作与实现(html+css+js+bootstarp)

  8. 分享java web 期末项目实验源码20套,BBS论坛,ERP管理系统,OA自动化等等

    分享java web 期末项目实验源码20套,BBS论坛,ERP管理系统,OA自动化等等 我自己也从里面学习到了很多东西! 1.BBS论坛系统(jsp+sql) 2.ERP管理系统(jsp+servl ...

  9. 软件工程专业期末项目开发全流程模拟日志(第一天)

    引言 本人软件工程专业大三在读,之前几学期的期末项目写得稀碎,虽然勉强能看,但是难登大雅之堂.此后几学期,决定严格按照软件开发过程去实现自己大大小小的开发项目,为我的毕设做准备,为我的工作做准备. 分 ...

最新文章

  1. python list去掉引号_最新的python面试题集170之三(基础性学习)
  2. 结合Jexus + Kestrel 部署 asp.net core 生产环境
  3. java绘制地球绕太阳转_Unity3D 公转小案例:地球围绕太阳转
  4. ajax get请求成功,成功()函数的AJAX GET请求
  5. 深度学习-函数-tf.nn.embedding_lookup 与tf.keras.layers.Embedding
  6. Java 7 对ArrayList和HashMap的性能的提升
  7. hitool备份3798固件方法_创维E900s海思3798芯片当贝桌面不拆机通刷固件及刷机教程201910版...
  8. unicode官网 unicode码表和标准下载
  9. [dataTables使用的坑]requested unknown parameter 'XXX' for row xx, column xx
  10. Logstash配置插件grok详解
  11. 【Python】matplotlib画图设置标题、轴标签、刻度、刻度标签(系列1)
  12. 洛谷 P3817 小A的糖果
  13. 香港电影金像奖23年全面回顾
  14. 破解AI开课难题!2021 全国人工智能师资培训落地厦门大学
  15. 推理规则/经典规则(排中律/反证法双重否定消除)
  16. matlab 将txt导入excel,[转载]MATLAB  批量导入excel和txt文件的方法
  17. 金税三期很可怕?好会计对症下药!
  18. 新世纪英语综合教程4(第二版)单元课后选词填空汇总
  19. 打造USB系统维护盘(GRUB,PE),U盘安装ubuntu、fedora、linux、windows
  20. 视频会议成未来办公趋势 四个问题需重视

热门文章

  1. Qt中的d指针和q指针
  2. asp.net 中Button按钮失效问题解决办法
  3. 非银金融行业:平安好医生,互联网医疗先行者,打造医疗生态圈闭环-20210106.PDF
  4. L2-040 哲哲打游戏 (25 分) 模拟
  5. 理解bpmn先从他的基本元素入手
  6. VS2019生成Steup文件在其他处理器运行
  7. 需求文档 BUC UC
  8. 论文查询:如何查询论文被其他哪些文献引用过?
  9. 决策过程并举例_体外诊断产品立项与研发的过程管理之二:产品的设计开发(二)...
  10. 华为C语言面试题(转!)