├── DomzSpider.py
├── README.md
├── back_end.php
├── build
├── build.js
├── check-versions.js
├── dev-client.js
├── dev-server.js
├── utils.js
├── vue-loader.conf.js
├── webpack.base.conf.js
├── webpack.dev.conf.js
├── webpack.prod.conf.js
└── webpack.test.conf.js
├── config
├── dev.env.js
├── index.js
├── prod.env.js
└── test.env.js
├── dist
├── index.html
└── static
│ ├── css
│ ├── app.bc6bcebd8dff1469ed2a180d243d1fb1.css
│ └── app.bc6bcebd8dff1469ed2a180d243d1fb1.css.map
│ └── js
│ ├── app.2e2f3fd3b6a1a7409115.js
│ ├── app.2e2f3fd3b6a1a7409115.js.map
│ ├── manifest.42e3257fe0dc6f03a838.js
│ ├── manifest.42e3257fe0dc6f03a838.js.map
│ ├── vendor.080f64fd4ca0f1bcf027.js
│ └── vendor.080f64fd4ca0f1bcf027.js.map
├── image
├── img1.png
├── img2.png
├── img3.png
└── img4.png
├── index.html
├── jsonToMySQL.py
├── package.json
├── src
├── App.vue
├── assets
│ └── logo.png
├── components
│ ├── searchEngine.vue
│ └── searchResult.vue
├── main.js
└── router
│ └── index.js
├── test
├── e2e
│ ├── custom-assertions
│ │ └── elementCount.js
│ ├── nightwatch.conf.js
│ ├── runner.js
│ └── specs
│ │ └── test.js
└── unit
│ ├── index.js
│ ├── karma.conf.js
│ └── specs
│ └── Hello.spec.js
└── urlToKeywords.py
/DomzSpider.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #from scrapy.spider import BaseSpider
3 | from scrapy.contrib.spiders import CrawlSpider,Rule
4 | from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
5 | from scrapy.dupefilter import RFPDupeFilter
6 | from scrapy.selector import HtmlXPathSelector
7 | from searchEngine.items import SearchengineItem
8 | class DmozSpider(CrawlSpider):
9 | name = "dmoz"
10 | allowed_domains = [
11 | "news.cn",
12 | "news.xinhuanet.com"
13 | ]
14 | start_urls = [
15 | "http://www.news.cn/",
16 | "http://www.news.cn/mil/index.htm",
17 | "http://www.news.cn/politics/"
18 | "http://www.news.cn/world/index.htm",
19 | "http://www.news.cn/tech/index.htm"
20 | ]
21 | rules = (
22 | #Rule(SgmlLinkExtractor(allow=('page/[0-9]+', ))),
23 | #Rule(SgmlLinkExtractor(allow=['/' ]),'item_parse')
24 | Rule(SgmlLinkExtractor(allow=('/', )),callback='item_parse'),
25 | )
26 | def item_parse(self,response,dont_filter=False):
27 | #self.log("%s"%response.url)
28 | item = SearchengineItem()
29 | item['url'] = response.url
30 | item['title'] = response.selector.xpath('//title/text()').extract()
31 | item['keywords'] = response.selector.xpath('//meta[@name="keywords"]/@content').extract()
32 | item['description'] = response.selector.xpath('//meta[@name="description"]/@content').extract()
33 | for t in item['title']:
34 | print t.encode('utf-8')
35 | for t in item['keywords']:
36 | print t.encode('utf-8')
37 | for t in item['description']:
38 | print t.encode('utf-8')
39 | return item
40 |
41 | #print item['title']
42 | '''
43 | def parse(self, response):
44 | #hxs = HtmlXPathSelector(response)
45 | #sites = hxs.select('//head')
46 | #res = HtmlXPathSelector(response)
47 |
48 | item = SearchengineItem()
49 | #for site in sites:
50 | # item = SearchengineItem()
51 | # item['title'] = site.select('//title/text()').extract()
52 | # item['link'] = site.select('meta/@keywords').extract()
53 | #item['desc'] = site.select('text()').extract()
54 | #items.append(item)
55 | item['title'] = response.selector.xpath('//title/text()').extract()
56 | item['keywords'] = response.selector.xpath('//meta[@name="keywords"]/@content').extract()
57 | item['description'] = response.selector.xpath('//meta[@name="description"]/@content').extract()
58 | for t in item['title']:
59 | print t.encode('utf-8')
60 | for t in item['keywords']:
61 | print t.encode('utf-8')
62 | for t in item['description']:
63 | print t.encode('utf-8')
64 | #print item['title']
65 | return item
66 |
67 | '''
68 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 小型搜索引擎(tinySearchEngine)
2 |
3 | > 基于scrapy爬虫框架,结巴分词,php和vue.js实现的小型搜索引擎。
4 | >
5 | > a tiny search engine based on vue.js and use scrapy,jieba,php to accomplish it
6 |
7 | ### Build Setup
8 |
9 | ``` bash
10 | # install dependencies
11 | npm install
12 |
13 | # serve with hot reload at localhost:8080
14 | npm run dev
15 |
16 | # build for production with minification
17 | npm run build
18 |
19 | # build for production and view the bundle analyzer report
20 | npm run build --report
21 | ```
22 |
23 | ### 整体实现
24 |
25 | 大体流程如下:
26 |
27 | 1.爬虫爬取网页数据,保存在文件中,
28 |
29 | 2.python读取文件内容,存到数据库表中,使用结巴分词对网页内容进行分词,并获得TF-IDF值,构建倒排索引保存到数据库中。
30 |
31 | 3.前端界面接受用户输入,使用POST请求将数据发送到后端。
32 |
33 | 4.后端接受到数据进行分词,然后在倒排索引数据库查询,结果取并集,然后根据倒排索引数据库结果在结果数据库中查询,返回网页的具体信息。
34 |
35 | 5.前端收到返回后,将结果呈现出来。
36 |
37 | ### 具体实现
38 |
39 | #### 1.爬虫
40 |
41 | 爬虫采用的是python的爬虫库scrapy,只需要进行简单的配置就可以使用,如果要递归爬取,可以采用`class DmozSpider(CrawlSpider)`。
42 |
43 | 要获得的数据网页数据主要有:url,title,description,keywords,具体配置如下:
44 |
45 | ```python
46 | item['title'] = response.selector.xpath('//title/text()').extract()
47 | item['keywords'] = response.selector.xpath('//meta[@name="keywords"]/@content').extract()
48 | item['description'] = response.selector.xpath('//meta[@name="description"]/@content').extract()
49 | ```
50 |
51 | 同时,为了保存数据,需要定义items,在items.py中添加如下:
52 |
53 | ```python
54 | url = scrapy.Field()
55 | title = scrapy.Field()
56 | keywords = scrapy.Field()
57 | description = scrapy.Field()
58 | ```
59 |
60 | 在终端中运行`scrapy crawl dmoz -o items.json -t json`,可以把数据存到items.json中。
61 |
62 | #### 2.分词
63 |
64 | 分词我选用的是python环境下的[结巴分词](https://github.com/fxsjy/jieba), 在考虑了好几种分词后,最后选择了结巴分词,主要是安装简单(可以直接通过pip安装),使用方便,并且在社区的贡献下,衍生出了不同语言版本(在后端中,我采用的是结巴分词的php版本)。
65 |
66 | 结巴分词直接提供了基于TF-IDF算法的关键词提取功能:
67 |
68 | > jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
69 | >
70 | > sentence 为待提取的文本
71 | >
72 | > topK 为返回几个 TF/IDF 权重最大的关键词,默认值为 20
73 | >
74 | > withWeight 为是否一并返回关键词权重值,默认值为 Falseallow
75 | >
76 | > POS 仅包括指定词性的词,默认值为空,即不筛选
77 |
78 | 所以在分词过程中,可以直接通过结巴分词获得关键词,以及关键词对应的TF-IDF值。
79 |
80 | #### 3.数据库
81 |
82 | 数据库选择的是MySQL,新建数据库名`python`,数据库下有两个表,`search_result`,`inverted index`。
83 |
84 | ```
85 | ├── python //数据库
86 | │ ├── search_result //搜索结果
87 | │ └── inverted indexsuoyin //倒排索引
88 | ```
89 |
90 | 经过爬虫爬取的数据保存在items.json中,在jsonToMySQL.py中,将文件中保存的数据存到数据库表search_result中,有index作为网页的唯一标志,字段有`index_`,`url`,`title`,`date`,`description`。
91 |
92 | 在urlToKeywords.py中,从表search_result中读取每一条,利用结巴分词提取关键字,并获得每个关键词的TF-IDF值,保存到表`inverted index`中,在查询的过程中,输入一条语句,将这条语句分词后得到关键词,将每个关键词进inverted index中查询,得到index和TF-IDF,结果取并集,根据index到search_result查询url,title等信息,利用TF-IDF之和进行页面的排序。
93 |
94 | #### 4.前端
95 |
96 | 前端采用前端框架`vue.js`,`使用vue-router`实现路由管理,使用`axios`发送http请求。组件有两个,模仿的是百度的首页,在有输入的时候输入框位置变化(百度打开时输入框居中,有输入的时候变换到输入框在顶部),百度应该是用切换css类的方式来实现的,我采用的是切换组件,首页输入框有输入改变触发`{{n}}
135 | ```
136 |
137 | 结果显示
138 |
139 | ```html
140 |
146 | ```
147 |
148 | 利用计算属性,只显示十个结果,并根据当前页的不同显示不同的结果。
149 |
150 | ```javascript
151 | part_response: function(){
152 | var part=[]
153 | for(let start = (this.page_select-1)*10;startquery($sql);
33 |
34 | if(!$result){
35 | echo json_encode("");
36 | //echo "sql语句错误
";
37 | //echo "error:".$mysqli->error."|".$mysqli->error;
38 | }
39 | $num_results = $result -> num_rows; //结果行数
40 | //echo "Number of row found: ". $num_results ."
";//输出行数
41 | global $result_array;
42 | for($i = 0;$i < $num_results;$i++)//循环输出每组元素
43 | {
44 | $row = $result -> fetch_assoc();//提取元素,一次一行,fetch_assoc()提取出的元素,有属性以及值
45 | $index_ = stripcslashes(($row['index_']));
46 | $tf_idf = stripcslashes($row['tf_idf']);
47 | //echo $index_." ".$tf_idf." ";
48 | if(array_key_exists($index_,$result_array)){
49 | $result_array[$index_]+=$tf_idf;
50 | }
51 | else{
52 | $result_array[$index_] = 0+$tf_idf;
53 | }
54 | }
55 |
56 | //mysqli_close($link);
57 | }
58 | function search($index){
59 | global $return_array;
60 | //$link = mysqli_connect("localhost", "root", "666666", "python");
61 | global $link;
62 | mysqli_set_charset($link, "utf8");
63 | /* check connection */
64 | if (mysqli_connect_errno()) {
65 | echo json_encode("");
66 | exit();
67 | }
68 |
69 | $sql = "select * from `search_result` where index_='".$index."'";
70 |
71 | $result=$link->query($sql);
72 |
73 | $num_results = $result -> num_rows; //结果行数
74 | $row = $result -> fetch_assoc();//提取元素,一次一行,fetch_assoc()提取出的元素,有属性以及值
75 | $url = stripcslashes(($row['url']));
76 | $title = stripcslashes($row['title']);
77 | $description = stripcslashes($row['description']);
78 | $date = stripcslashes($row['date']);
79 | $return_array[]=array("url"=>$url,"title"=>$title,"description"=>$description,"date"=>$date);
80 | //mysqli_close($link);
81 | }
82 | session_start();
83 |
84 | // $_POST['question']='大约';
85 | if($_POST['question']!=""){
86 | //$_SESSION["Jie"]=serialize(Jieba::return_self());
87 | //unserialize($_SESSION["Jie"])::init();
88 | Jieba::init();
89 | Finalseg::init();
90 | //open database
91 | $link = mysqli_connect("localhost", "root", "666666", "python");
92 |
93 |
94 | $result_array=[];
95 | $return_array=[];
96 | $seg_list=Jieba::cutForSearch($_POST['question']);
97 | //$seg_list = unserialize($_SESSION["Jie"])::cutForSearch($_POST['question']);
98 | //var_dump($seg_list);
99 | if(count($seg_list)==0){
100 | echo json_encode("");
101 | exit();
102 | }
103 | foreach ($seg_list as $value){
104 | //print($value." ");
105 | find($value);
106 | }
107 | if(count($result_array)==0){
108 | echo json_encode("");
109 | exit();
110 | }
111 | arsort($result_array);
112 | foreach ($result_array as $key=>$value){
113 | search($key);
114 | }
115 | if(count($return_array)==0){
116 | echo json_encode("");
117 | exit();
118 | }
119 | echo json_encode($return_array);
120 |
121 | //close database
122 | mysqli_close($link);
123 |
124 | }
125 | ?>
126 |
--------------------------------------------------------------------------------
/build/build.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 |
3 | process.env.NODE_ENV = 'production'
4 |
5 | var ora = require('ora')
6 | var rm = require('rimraf')
7 | var path = require('path')
8 | var chalk = require('chalk')
9 | var webpack = require('webpack')
10 | var config = require('../config')
11 | var webpackConfig = require('./webpack.prod.conf')
12 |
13 | var spinner = ora('building for production...')
14 | spinner.start()
15 |
16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
17 | if (err) throw err
18 | webpack(webpackConfig, function (err, stats) {
19 | spinner.stop()
20 | if (err) throw err
21 | process.stdout.write(stats.toString({
22 | colors: true,
23 | modules: false,
24 | children: false,
25 | chunks: false,
26 | chunkModules: false
27 | }) + '\n\n')
28 |
29 | console.log(chalk.cyan(' Build complete.\n'))
30 | console.log(chalk.yellow(
31 | ' Tip: built files are meant to be served over an HTTP server.\n' +
32 | ' Opening index.html over file:// won\'t work.\n'
33 | ))
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/build/check-versions.js:
--------------------------------------------------------------------------------
1 | var chalk = require('chalk')
2 | var semver = require('semver')
3 | var packageConfig = require('../package.json')
4 | var shell = require('shelljs')
5 | function exec (cmd) {
6 | return require('child_process').execSync(cmd).toString().trim()
7 | }
8 |
9 | var versionRequirements = [
10 | {
11 | name: 'node',
12 | currentVersion: semver.clean(process.version),
13 | versionRequirement: packageConfig.engines.node
14 | },
15 | ]
16 |
17 | if (shell.which('npm')) {
18 | versionRequirements.push({
19 | name: 'npm',
20 | currentVersion: exec('npm --version'),
21 | versionRequirement: packageConfig.engines.npm
22 | })
23 | }
24 |
25 | module.exports = function () {
26 | var warnings = []
27 | for (var i = 0; i < versionRequirements.length; i++) {
28 | var mod = versionRequirements[i]
29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
30 | warnings.push(mod.name + ': ' +
31 | chalk.red(mod.currentVersion) + ' should be ' +
32 | chalk.green(mod.versionRequirement)
33 | )
34 | }
35 | }
36 |
37 | if (warnings.length) {
38 | console.log('')
39 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
40 | console.log()
41 | for (var i = 0; i < warnings.length; i++) {
42 | var warning = warnings[i]
43 | console.log(' ' + warning)
44 | }
45 | console.log()
46 | process.exit(1)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/build/dev-client.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('eventsource-polyfill')
3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
4 |
5 | hotClient.subscribe(function (event) {
6 | if (event.action === 'reload') {
7 | window.location.reload()
8 | }
9 | })
10 |
--------------------------------------------------------------------------------
/build/dev-server.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 |
3 | var config = require('../config')
4 | if (!process.env.NODE_ENV) {
5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
6 | }
7 |
8 | var opn = require('opn')
9 | var path = require('path')
10 | var express = require('express')
11 | var webpack = require('webpack')
12 | var proxyMiddleware = require('http-proxy-middleware')
13 | var webpackConfig = process.env.NODE_ENV === 'testing'
14 | ? require('./webpack.prod.conf')
15 | : require('./webpack.dev.conf')
16 |
17 | // default port where dev server listens for incoming traffic
18 | var port = process.env.PORT || config.dev.port
19 | // automatically open browser, if not set will be false
20 | var autoOpenBrowser = !!config.dev.autoOpenBrowser
21 | // Define HTTP proxies to your custom API backend
22 | // https://github.com/chimurai/http-proxy-middleware
23 | var proxyTable = config.dev.proxyTable
24 |
25 | var app = express()
26 | var compiler = webpack(webpackConfig)
27 |
28 | var devMiddleware = require('webpack-dev-middleware')(compiler, {
29 | publicPath: webpackConfig.output.publicPath,
30 | quiet: true
31 | })
32 |
33 | var hotMiddleware = require('webpack-hot-middleware')(compiler, {
34 | log: () => {}
35 | })
36 | // force page reload when html-webpack-plugin template changes
37 | compiler.plugin('compilation', function (compilation) {
38 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
39 | hotMiddleware.publish({ action: 'reload' })
40 | cb()
41 | })
42 | })
43 |
44 | // proxy api requests
45 | Object.keys(proxyTable).forEach(function (context) {
46 | var options = proxyTable[context]
47 | if (typeof options === 'string') {
48 | options = { target: options }
49 | }
50 | app.use(proxyMiddleware(options.filter || context, options))
51 | })
52 |
53 | // handle fallback for HTML5 history API
54 | app.use(require('connect-history-api-fallback')())
55 |
56 | // serve webpack bundle output
57 | app.use(devMiddleware)
58 |
59 | // enable hot-reload and state-preserving
60 | // compilation error display
61 | app.use(hotMiddleware)
62 |
63 | // serve pure static assets
64 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
65 | app.use(staticPath, express.static('./static'))
66 |
67 | var uri = 'http://localhost:' + port
68 |
69 | var _resolve
70 | var readyPromise = new Promise(resolve => {
71 | _resolve = resolve
72 | })
73 |
74 | console.log('> Starting dev server...')
75 | devMiddleware.waitUntilValid(() => {
76 | console.log('> Listening at ' + uri + '\n')
77 | // when env is testing, don't need open it
78 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
79 | opn(uri)
80 | }
81 | _resolve()
82 | })
83 |
84 | var server = app.listen(port)
85 |
86 | module.exports = {
87 | ready: readyPromise,
88 | close: () => {
89 | server.close()
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/build/utils.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var config = require('../config')
3 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
4 |
5 | exports.assetsPath = function (_path) {
6 | var assetsSubDirectory = process.env.NODE_ENV === 'production'
7 | ? config.build.assetsSubDirectory
8 | : config.dev.assetsSubDirectory
9 | return path.posix.join(assetsSubDirectory, _path)
10 | }
11 |
12 | exports.cssLoaders = function (options) {
13 | options = options || {}
14 |
15 | var cssLoader = {
16 | loader: 'css-loader',
17 | options: {
18 | minimize: process.env.NODE_ENV === 'production',
19 | sourceMap: options.sourceMap
20 | }
21 | }
22 |
23 | // generate loader string to be used with extract text plugin
24 | function generateLoaders (loader, loaderOptions) {
25 | var loaders = [cssLoader]
26 | if (loader) {
27 | loaders.push({
28 | loader: loader + '-loader',
29 | options: Object.assign({}, loaderOptions, {
30 | sourceMap: options.sourceMap
31 | })
32 | })
33 | }
34 |
35 | // Extract CSS when that option is specified
36 | // (which is the case during production build)
37 | if (options.extract) {
38 | return ExtractTextPlugin.extract({
39 | use: loaders,
40 | fallback: 'vue-style-loader'
41 | })
42 | } else {
43 | return ['vue-style-loader'].concat(loaders)
44 | }
45 | }
46 |
47 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
48 | return {
49 | css: generateLoaders(),
50 | postcss: generateLoaders(),
51 | less: generateLoaders('less'),
52 | sass: generateLoaders('sass', { indentedSyntax: true }),
53 | scss: generateLoaders('sass'),
54 | stylus: generateLoaders('stylus'),
55 | styl: generateLoaders('stylus')
56 | }
57 | }
58 |
59 | // Generate loaders for standalone style files (outside of .vue)
60 | exports.styleLoaders = function (options) {
61 | var output = []
62 | var loaders = exports.cssLoaders(options)
63 | for (var extension in loaders) {
64 | var loader = loaders[extension]
65 | output.push({
66 | test: new RegExp('\\.' + extension + '$'),
67 | use: loader
68 | })
69 | }
70 | return output
71 | }
72 |
--------------------------------------------------------------------------------
/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils')
2 | var config = require('../config')
3 | var isProduction = process.env.NODE_ENV === 'production'
4 |
5 | module.exports = {
6 | loaders: utils.cssLoaders({
7 | sourceMap: isProduction
8 | ? config.build.productionSourceMap
9 | : config.dev.cssSourceMap,
10 | extract: isProduction
11 | })
12 | }
13 |
--------------------------------------------------------------------------------
/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var utils = require('./utils')
3 | var config = require('../config')
4 | var vueLoaderConfig = require('./vue-loader.conf')
5 |
6 | function resolve (dir) {
7 | return path.join(__dirname, '..', dir)
8 | }
9 |
10 | module.exports = {
11 | entry: {
12 | app: './src/main.js'
13 | },
14 | output: {
15 | path: config.build.assetsRoot,
16 | filename: '[name].js',
17 | publicPath: process.env.NODE_ENV === 'production'
18 | ? config.build.assetsPublicPath
19 | : config.dev.assetsPublicPath
20 | },
21 | resolve: {
22 | extensions: ['.js', '.vue', '.json'],
23 | alias: {
24 | 'vue$': 'vue/dist/vue.esm.js',
25 | '@': resolve('src')
26 | }
27 | },
28 | module: {
29 | rules: [
30 | {
31 | test: /\.vue$/,
32 | loader: 'vue-loader',
33 | options: vueLoaderConfig
34 | },
35 | {
36 | test: /\.js$/,
37 | loader: 'babel-loader',
38 | include: [resolve('src'), resolve('test')]
39 | },
40 | {
41 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
42 | loader: 'url-loader',
43 | options: {
44 | limit: 10000,
45 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
46 | }
47 | },
48 | {
49 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
50 | loader: 'url-loader',
51 | options: {
52 | limit: 10000,
53 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
54 | }
55 | }
56 | ]
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils')
2 | var webpack = require('webpack')
3 | var config = require('../config')
4 | var merge = require('webpack-merge')
5 | var baseWebpackConfig = require('./webpack.base.conf')
6 | var HtmlWebpackPlugin = require('html-webpack-plugin')
7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
8 |
9 | // add hot-reload related code to entry chunks
10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) {
11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
12 | })
13 |
14 | module.exports = merge(baseWebpackConfig, {
15 | module: {
16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
17 | },
18 | // cheap-module-eval-source-map is faster for development
19 | devtool: '#cheap-module-eval-source-map',
20 | plugins: [
21 | new webpack.DefinePlugin({
22 | 'process.env': config.dev.env
23 | }),
24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
25 | new webpack.HotModuleReplacementPlugin(),
26 | new webpack.NoEmitOnErrorsPlugin(),
27 | // https://github.com/ampedandwired/html-webpack-plugin
28 | new HtmlWebpackPlugin({
29 | filename: 'index.html',
30 | template: 'index.html',
31 | inject: true
32 | }),
33 | new FriendlyErrorsPlugin()
34 | ]
35 | })
36 |
--------------------------------------------------------------------------------
/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var utils = require('./utils')
3 | var webpack = require('webpack')
4 | var config = require('../config')
5 | var merge = require('webpack-merge')
6 | var baseWebpackConfig = require('./webpack.base.conf')
7 | var CopyWebpackPlugin = require('copy-webpack-plugin')
8 | var HtmlWebpackPlugin = require('html-webpack-plugin')
9 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
10 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
11 |
12 | var env = process.env.NODE_ENV === 'testing'
13 | ? require('../config/test.env')
14 | : config.build.env
15 |
16 | var webpackConfig = merge(baseWebpackConfig, {
17 | module: {
18 | rules: utils.styleLoaders({
19 | sourceMap: config.build.productionSourceMap,
20 | extract: true
21 | })
22 | },
23 | devtool: config.build.productionSourceMap ? '#source-map' : false,
24 | output: {
25 | path: config.build.assetsRoot,
26 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
27 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
28 | },
29 | plugins: [
30 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
31 | new webpack.DefinePlugin({
32 | 'process.env': env
33 | }),
34 | new webpack.optimize.UglifyJsPlugin({
35 | compress: {
36 | warnings: false
37 | },
38 | sourceMap: true
39 | }),
40 | // extract css into its own file
41 | new ExtractTextPlugin({
42 | filename: utils.assetsPath('css/[name].[contenthash].css')
43 | }),
44 | // Compress extracted CSS. We are using this plugin so that possible
45 | // duplicated CSS from different components can be deduped.
46 | new OptimizeCSSPlugin({
47 | cssProcessorOptions: {
48 | safe: true
49 | }
50 | }),
51 | // generate dist index.html with correct asset hash for caching.
52 | // you can customize output by editing /index.html
53 | // see https://github.com/ampedandwired/html-webpack-plugin
54 | new HtmlWebpackPlugin({
55 | filename: process.env.NODE_ENV === 'testing'
56 | ? 'index.html'
57 | : config.build.index,
58 | template: 'index.html',
59 | inject: true,
60 | minify: {
61 | removeComments: true,
62 | collapseWhitespace: true,
63 | removeAttributeQuotes: true
64 | // more options:
65 | // https://github.com/kangax/html-minifier#options-quick-reference
66 | },
67 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
68 | chunksSortMode: 'dependency'
69 | }),
70 | // split vendor js into its own file
71 | new webpack.optimize.CommonsChunkPlugin({
72 | name: 'vendor',
73 | minChunks: function (module, count) {
74 | // any required modules inside node_modules are extracted to vendor
75 | return (
76 | module.resource &&
77 | /\.js$/.test(module.resource) &&
78 | module.resource.indexOf(
79 | path.join(__dirname, '../node_modules')
80 | ) === 0
81 | )
82 | }
83 | }),
84 | // extract webpack runtime and module manifest to its own file in order to
85 | // prevent vendor hash from being updated whenever app bundle is updated
86 | new webpack.optimize.CommonsChunkPlugin({
87 | name: 'manifest',
88 | chunks: ['vendor']
89 | }),
90 | // copy custom static assets
91 | new CopyWebpackPlugin([
92 | {
93 | from: path.resolve(__dirname, '../static'),
94 | to: config.build.assetsSubDirectory,
95 | ignore: ['.*']
96 | }
97 | ])
98 | ]
99 | })
100 |
101 | if (config.build.productionGzip) {
102 | var CompressionWebpackPlugin = require('compression-webpack-plugin')
103 |
104 | webpackConfig.plugins.push(
105 | new CompressionWebpackPlugin({
106 | asset: '[path].gz[query]',
107 | algorithm: 'gzip',
108 | test: new RegExp(
109 | '\\.(' +
110 | config.build.productionGzipExtensions.join('|') +
111 | ')$'
112 | ),
113 | threshold: 10240,
114 | minRatio: 0.8
115 | })
116 | )
117 | }
118 |
119 | if (config.build.bundleAnalyzerReport) {
120 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
121 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
122 | }
123 |
124 | module.exports = webpackConfig
125 |
--------------------------------------------------------------------------------
/build/webpack.test.conf.js:
--------------------------------------------------------------------------------
1 | // This is the webpack config used for unit tests.
2 |
3 | var utils = require('./utils')
4 | var webpack = require('webpack')
5 | var merge = require('webpack-merge')
6 | var baseConfig = require('./webpack.base.conf')
7 |
8 | var webpackConfig = merge(baseConfig, {
9 | // use inline sourcemap for karma-sourcemap-loader
10 | module: {
11 | rules: utils.styleLoaders()
12 | },
13 | devtool: '#inline-source-map',
14 | plugins: [
15 | new webpack.DefinePlugin({
16 | 'process.env': require('../config/test.env')
17 | })
18 | ]
19 | })
20 |
21 | // no need for app entry during tests
22 | delete webpackConfig.entry
23 |
24 | module.exports = webpackConfig
25 |
--------------------------------------------------------------------------------
/config/dev.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var prodEnv = require('./prod.env')
3 |
4 | module.exports = merge(prodEnv, {
5 | NODE_ENV: '"development"'
6 | })
7 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | // see http://vuejs-templates.github.io/webpack for documentation.
2 | var path = require('path')
3 |
4 | module.exports = {
5 | build: {
6 | env: require('./prod.env'),
7 | index: path.resolve(__dirname, '../dist/index.html'),
8 | assetsRoot: path.resolve(__dirname, '../dist'),
9 | assetsSubDirectory: 'static',
10 | assetsPublicPath: '/',
11 | productionSourceMap: true,
12 | // Gzip off by default as many popular static hosts such as
13 | // Surge or Netlify already gzip all static assets for you.
14 | // Before setting to `true`, make sure to:
15 | // npm install --save-dev compression-webpack-plugin
16 | productionGzip: false,
17 | productionGzipExtensions: ['js', 'css'],
18 | // Run the build command with an extra argument to
19 | // View the bundle analyzer report after build finishes:
20 | // `npm run build --report`
21 | // Set to `true` or `false` to always turn it on or off
22 | bundleAnalyzerReport: process.env.npm_config_report
23 | },
24 | dev: {
25 | env: require('./dev.env'),
26 | port: 8080,
27 | autoOpenBrowser: true,
28 | assetsSubDirectory: 'static',
29 | assetsPublicPath: '/',
30 | proxyTable: {},
31 | // CSS Sourcemaps off by default because relative paths are "buggy"
32 | // with this option, according to the CSS-Loader README
33 | // (https://github.com/webpack/css-loader#sourcemaps)
34 | // In our experience, they generally work as expected,
35 | // just be aware of this issue when enabling this option.
36 | cssSourceMap: false
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/config/prod.env.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | NODE_ENV: '"production"'
3 | }
4 |
--------------------------------------------------------------------------------
/config/test.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var devEnv = require('./dev.env')
3 |
4 | module.exports = merge(devEnv, {
5 | NODE_ENV: '"testing"'
6 | })
7 |
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 | search-engine
--------------------------------------------------------------------------------
/dist/static/css/app.bc6bcebd8dff1469ed2a180d243d1fb1.css:
--------------------------------------------------------------------------------
1 | #searchEngine[data-v-e082b27e]{left:30%;top:40%;width:100%;position:fixed;z-index:1;background-color:#fff}#text[data-v-e082b27e]{width:30%;height:41px;//border-style:solid;//border-width:1px;border:1px solid #39f;font-size:24px;padding:0;margin:-1px 0 0}#button[data-v-e082b27e]{//float:right;height:45px;width:7%;background-color:#39f;border-width:1px;border-style:solid;font-size:24px;color:#fff;margin:-2px 0 0 -5px;padding:0}.hightLight[data-v-17d40f1c]{color:red}#searchResult[data-v-17d40f1c]{width:100%;height:100%;margin:0;padding:0}#header[data-v-17d40f1c]{margin-top:0;padding:0;width:100%;height:80px;background-color:#fff;position:fixed;top:0;left:0;z-index:1}#input[data-v-17d40f1c]{width:600px;height:35px;border:1px solid #39f;font-size:24px;position:relative;left:15%;top:8px}#submit[data-v-17d40f1c]{height:40px;width:120px;background-color:#39f;border:none;//border-style:solid;font-size:24px;color:#fff;margin-top:-1px;//margin-left:-10px;position:relative;top:8px;left:10%}#result[data-v-17d40f1c]{height:auto;width:40%;margin-top:80px;position:relative;left:15%}#result_number[data-v-17d40f1c]{color:gray;font-size:16px}#result a[data-v-17d40f1c]{font-size:18px;color:#00f}#result p[data-v-17d40f1c]{margin:2px}#small_url_content[data-v-17d40f1c]{display:inline-block}#date[data-v-17d40f1c]{display:inline-block;font-size:12px;color:#666}#result li a[data-v-17d40f1c]{display:block;width:15em;word-break:keep-all;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:12px;text-decoration:none;color:#008b00}#footer[data-v-17d40f1c]{position:relative;left:15%}#footer button[data-v-17d40f1c]{margin-right:20px;font-size:15px;background-color:#fff;border:1px solid #fff;padding:10px 14px;//border:none;color:#191970}#footer button[data-v-17d40f1c]:hover{border:1px solid #39f;cursor:hand}
--------------------------------------------------------------------------------
/dist/static/css/app.bc6bcebd8dff1469ed2a180d243d1fb1.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///./src/components/searchEngine.vue","webpack:///./src/components/searchResult.vue"],"names":[],"mappings":"AACA,+BACI,SACA,QACA,WACA,eACA,UACA,qBAAuB,CAE3B,uBACI,UACA,YAEA,qBACA,mBACA,sBACA,eACA,UACA,eAAoB,CAExB,yBACI,cACA,YACA,SACA,sBACA,iBACA,mBACA,eACA,WACA,qBACA,SAAa,CC7BjB,6BACC,SAAW,CAEZ,+BACC,WACA,YACA,SACA,SAAW,CAEZ,yBACI,aACA,UACA,WACA,YACA,sBACA,eACA,MACA,OACA,SAAW,CAEf,wBACC,YACG,YACA,sBAGA,eACA,kBACA,SACA,OAAS,CAEb,yBACC,YACG,YACA,sBACA,YACA,qBACA,eACA,WACA,gBACA,oBACA,kBACA,QACA,QAAU,CAEd,yBACI,YACA,UACA,gBACA,kBACA,QAAU,CAEd,gCACC,WACA,cAAgB,CAEjB,2BACI,eACA,UAAe,CAEnB,2BACI,UAAW,CAOf,oCACC,oBAAsB,CAEvB,uBACC,qBACG,eACA,UAAe,CAEnB,8BACC,cACG,WACA,oBACA,mBACA,gBACA,uBACA,eACA,qBACA,aAAe,CAEnB,yBACC,kBACA,QAAU,CAEX,gCACC,kBACA,eACA,sBACA,sBACA,kBACA,cACA,aAAe,CAEhB,sCACC,sBACA,WAAa","file":"static/css/app.bc6bcebd8dff1469ed2a180d243d1fb1.css","sourcesContent":["\n#searchEngine[data-v-e082b27e]{\n left: 30%;\n top: 40%;\n width: 100%;\n position: fixed;\n z-index: 1;\n background-color: #FFF;\n}\n#text[data-v-e082b27e]{\n width: 30%;\n height: 41px;\n \n //border-style:solid;\n //border-width:1px;\n border: solid 1px #39F;\n font-size:24px;\n padding: 0px;\n margin:-1px 0 0 0px;\n}\n#button[data-v-e082b27e]{\n //float: right;\n height:45px;\n width:7%;\n background-color:#39F;\n border-width: 1px;\n border-style: solid;\n font-size:24px;\n color:#FFF;\n margin:-2px 0 0 -5px;\n padding: 0px;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/searchEngine.vue","\n.hightLight[data-v-17d40f1c]{\n\tcolor: red;\n}\n#searchResult[data-v-17d40f1c]{\n\twidth: 100%;\n\theight: 100%;\n\tmargin: 0;\n\tpadding: 0;\n}\n#header[data-v-17d40f1c]{\n margin-top: 0;\n padding: 0;\n width: 100%;\n height: 80px;\n background-color: #FFF;\n position: fixed;\n top: 0px;\n left: 0px;\n z-index: 1;\n}\n#input[data-v-17d40f1c]{\n\twidth: 600px;\n height: 35px;\n //border-color:#39F;\n border-style:solid;\n border-width:1px;\n font-size:24px;\n position: relative;\n left: 15%;\n top: 8px;\n}\n#submit[data-v-17d40f1c]{\n\theight:40px;\n width:120px;\n background-color:#39F;\n border:none;\n //border-style:solid;\n font-size:24px;\n color:#FFF;\n margin-top: -1px;\n //margin-left:-10px;\n position: relative;\n top: 8px;\n left: 10%;\n}\n#result[data-v-17d40f1c]{\n height: auto;\n width: 40%;\n margin-top: 80px;\n position: relative;\n left: 15%;\n}\n#result_number[data-v-17d40f1c]{\n\tcolor: gray;\n\tfont-size: 16px;\n}\n#result a[data-v-17d40f1c]{\n font-size: 18px;\n color: #0000FF;\n}\n#result p[data-v-17d40f1c]{\n margin:2px;\n}\n/*#result li{\n display: inline-block;\n font-size: 12px;\n color: #666666;\n}*/\n#small_url_content[data-v-17d40f1c]{\n\tdisplay: inline-block;\n}\n#date[data-v-17d40f1c]{\n\tdisplay: inline-block;\n font-size: 12px;\n color: #666666;\n}\n#result li a[data-v-17d40f1c]{\n\tdisplay:block;/*内联对象需加*/\n width:15em;\n word-break:keep-all;/* 不换行 */\n white-space:nowrap;/* 不换行 */\n overflow:hidden;/* 内容超出宽度时隐藏超出部分的内容 */\n text-overflow:ellipsis;/* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/\n font-size: 12px;\n text-decoration: none;\n color: #008B00;\n}\n#footer[data-v-17d40f1c]{\n\tposition: relative;\n\tleft: 15%;\n}\n#footer button[data-v-17d40f1c]{\n\tmargin-right:20px;\n\tfont-size: 15px;\n\tbackground-color: #FFF;\n\tborder:solid 1px #FFF;\n\tpadding: 10px 14px 10px 14px;\n\t//border:none;\n\tcolor: #191970;\n}\n#footer button[data-v-17d40f1c]:hover{\n\tborder:solid 1px #39F;\n\tcursor: hand;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/searchResult.vue"],"sourceRoot":""}
--------------------------------------------------------------------------------
/dist/static/js/app.2e2f3fd3b6a1a7409115.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([1],[,,,,,,,,,,,,,function(t,e,n){"use strict";var r=n(3),s=n(55),i=n(50),a=n.n(i),o=n(51),u=n.n(o);r.a.use(s.a),e.a=new s.a({routes:[{path:"/",name:"searchEngine",component:a.a},{path:"/result",name:"searchResult",component:u.a}]})},function(t,e,n){n(42);var r=n(2)(n(32),n(53),null,null);t.exports=r.exports},,,,,,,,,,,,,,,,,,function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={name:"app",data:function(){return{query:""}},methods:{showResult:function(t){this.query=t,console.log(this.query),this.$router.replace({path:"/result"})}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={name:"searchEngine",data:function(){return{query:""}},methods:{change:function(){this.$emit("childChange",this.query)},submit:function(){location.reload()}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(36),s=n.n(r);e.default={name:"searchResult",props:["parentQuery"],mounted:function(){document.getElementById("input").focus()},updated:function(){if(""!=this.query){var t,e=(this.query.split(""),document.getElementsByClassName("item_description")),n=document.getElementsByClassName("item_title"),r=new RegExp(this.query,"g");for(t in e){var s=e[t].innerHTML,i=n[t].innerHTML;i=i.replace(r,""+this.query+""),s=s.replace(r,""+this.query+""),e[t].innerHTML=s,n[t].innerHTML=i}}},data:function(){return{msg:"Welcome to Your Vue.js App",query:this.parentQuery,page_select:1,tips:"请输入要搜索的内容",show_button:!1,response:[]}},computed:{length:function(){var t=0;for(var e in this.response)t++;return t},part_response:function(){for(var t=[],e=10*(this.page_select-1);e<10*this.page_select;e++)e",components:{App:i.a}})},,,,,,function(t,e){},function(t,e){},function(t,e){},,,,,,,function(t,e,n){n(43);var r=n(2)(n(33),n(54),"data-v-e082b27e",null);t.exports=r.exports},function(t,e,n){n(41);var r=n(2)(n(34),n(52),"data-v-17d40f1c",null);t.exports=r.exports},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{attrs:{id:"searchResult"}},[n("div",{attrs:{id:"header"}},[n("input",{directives:[{name:"model",rawName:"v-model",value:t.query,expression:"query"}],attrs:{type:"text",id:"input"},domProps:{value:t.query},on:{keyup:function(e){if(!("button"in e)&&t._k(e.keyCode,"enter",13))return null;t.submit(e)},input:function(e){e.target.composing||(t.query=e.target.value)}}}),t._v(" "),n("button",{attrs:{id:"submit"},on:{click:t.submit}},[t._v("search")])]),t._v(" "),n("div",{attrs:{id:"result"}},[n("p",{attrs:{id:"result_number"}},[t._v(t._s(t.tips))]),t._v(" "),t._l(t.part_response,function(e){return n("div",[n("a",{staticClass:"item_title",attrs:{id:"title",href:e.url,target:"_blank"}},[t._v(t._s(e.title))]),t._v(" "),n("p",{staticClass:"item_description"},[t._v(t._s(e.description))]),t._v(" "),n("li",{attrs:{id:"small_url_content"}},[n("a",{attrs:{href:e.url,id:"small_url",target:"_blank"}},[t._v(t._s(e.url))])]),t._v(" "),n("li",{attrs:{id:"date"}},[t._v(" "+t._s(e.date))])])})],2),t._v(" "),n("div",{attrs:{id:"footer"}},t._l(parseInt(t.length/10)+1,function(e){return t.show_button?n("button",{on:{click:function(n){t.page_select=e}}},[t._v(t._s(e))]):t._e()}))])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{attrs:{id:"app"}},[n("router-view",{attrs:{"parent-query":t.query},on:{childChange:t.showResult}})],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{attrs:{id:"searchEngine"}},[n("input",{directives:[{name:"model",rawName:"v-model",value:t.query,expression:"query"}],attrs:{type:"text",id:"text"},domProps:{value:t.query},on:{input:[function(e){e.target.composing||(t.query=e.target.value)},t.change]}}),t._v(" "),n("button",{attrs:{id:"button"},on:{click:t.submit}},[t._v("search")])])},staticRenderFns:[]}}],[35]);
2 | //# sourceMappingURL=app.2e2f3fd3b6a1a7409115.js.map
--------------------------------------------------------------------------------
/dist/static/js/app.2e2f3fd3b6a1a7409115.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///static/js/app.2e2f3fd3b6a1a7409115.js","webpack:///./src/router/index.js","webpack:///./src/App.vue","webpack:///App.vue","webpack:///searchEngine.vue","webpack:///searchResult.vue","webpack:///./src/main.js","webpack:///./src/components/searchEngine.vue?297e","webpack:///./src/components/searchResult.vue?72a3","webpack:///./src/components/searchResult.vue?cd92","webpack:///./src/App.vue?0d65","webpack:///./src/components/searchEngine.vue?0821"],"names":["webpackJsonp","module","__webpack_exports__","__webpack_require__","__WEBPACK_IMPORTED_MODULE_0_vue__","__WEBPACK_IMPORTED_MODULE_1_vue_router__","__WEBPACK_IMPORTED_MODULE_2__components_searchEngine__","__WEBPACK_IMPORTED_MODULE_2__components_searchEngine___default","n","__WEBPACK_IMPORTED_MODULE_3__components_searchResult__","__WEBPACK_IMPORTED_MODULE_3__components_searchResult___default","use","routes","path","name","component","a","exports","Component","Object","defineProperty","value","data","query","methods","showResult","this","console","log","$router","replace","change","$emit","submit","location","reload","__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_json_stringify__","__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_json_stringify___default","props","mounted","document","getElementById","focus","updated","index","item_description","split","getElementsByClassName","item_title","re","RegExp","description_text","innerHTML","title_text","msg","parentQuery","page_select","tips","show_button","response","computed","length","len","item","part_response","part","start","push","split_query","_this","qs","$axios","post","stringify","question","then","catch","error","__WEBPACK_IMPORTED_MODULE_1__App__","__WEBPACK_IMPORTED_MODULE_1__App___default","__WEBPACK_IMPORTED_MODULE_2__router__","__WEBPACK_IMPORTED_MODULE_3_axios__","__WEBPACK_IMPORTED_MODULE_3_axios___default","defaults","headers","prototype","config","productionTip","el","router","template","components","App","render","_vm","_h","$createElement","_c","_self","attrs","id","directives","rawName","expression","type","domProps","on","keyup","$event","_k","keyCode","input","target","composing","_v","click","_s","_l","staticClass","href","url","title","description","date","parseInt","_e","staticRenderFns","parent-query","childChange"],"mappings":"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","file":"static/js/app.2e2f3fd3b6a1a7409115.js","sourcesContent":["webpackJsonp([1],[\n/* 0 */,\n/* 1 */,\n/* 2 */,\n/* 3 */,\n/* 4 */,\n/* 5 */,\n/* 6 */,\n/* 7 */,\n/* 8 */,\n/* 9 */,\n/* 10 */,\n/* 11 */,\n/* 12 */,\n/* 13 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_vue__ = __webpack_require__(3);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_vue_router__ = __webpack_require__(55);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__components_searchEngine__ = __webpack_require__(50);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__components_searchEngine___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2__components_searchEngine__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__components_searchResult__ = __webpack_require__(51);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__components_searchResult___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3__components_searchResult__);\n\n\n\n\n\n__WEBPACK_IMPORTED_MODULE_0_vue__[\"a\" /* default */].use(__WEBPACK_IMPORTED_MODULE_1_vue_router__[\"a\" /* default */]);\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (new __WEBPACK_IMPORTED_MODULE_1_vue_router__[\"a\" /* default */]({\n routes: [{\n path: '/',\n name: 'searchEngine',\n component: __WEBPACK_IMPORTED_MODULE_2__components_searchEngine___default.a\n }, {\n path: '/result',\n name: 'searchResult',\n component: __WEBPACK_IMPORTED_MODULE_3__components_searchResult___default.a\n }]\n}));\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\n/* styles */\n__webpack_require__(42)\n\nvar Component = __webpack_require__(2)(\n /* script */\n __webpack_require__(32),\n /* template */\n __webpack_require__(53),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ }),\n/* 15 */,\n/* 16 */,\n/* 17 */,\n/* 18 */,\n/* 19 */,\n/* 20 */,\n/* 21 */,\n/* 22 */,\n/* 23 */,\n/* 24 */,\n/* 25 */,\n/* 26 */,\n/* 27 */,\n/* 28 */,\n/* 29 */,\n/* 30 */,\n/* 31 */,\n/* 32 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n name: 'app',\n data: function data() {\n return {\n query: ''\n };\n },\n\n methods: {\n showResult: function showResult(data) {\n this.query = data;\n console.log(this.query);\n this.$router.replace({ path: '/result' });\n }\n }\n});\n\n/***/ }),\n/* 33 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n name: 'searchEngine',\n data: function data() {\n return {\n query: ''\n\n };\n },\n\n methods: {\n change: function change() {\n this.$emit('childChange', this.query);\n },\n submit: function submit() {\n location.reload();\n }\n }\n});\n\n/***/ }),\n/* 34 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_json_stringify__ = __webpack_require__(36);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_json_stringify___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_json_stringify__);\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n name: 'searchResult',\n props: ['parentQuery'],\n mounted: function mounted() {\n var input_query = document.getElementById('input');\n input_query.focus();\n },\n updated: function updated() {\n if (this.query != \"\") {\n var split_query = this.query.split(\"\");\n var item_description = document.getElementsByClassName('item_description');\n var item_title = document.getElementsByClassName('item_title');\n var re = new RegExp(this.query, \"g\");\n var index;\n for (index in item_description) {\n var description_text = item_description[index].innerHTML;\n var title_text = item_title[index].innerHTML;\n title_text = title_text.replace(re, \"\" + this.query + \"\");\n description_text = description_text.replace(re, \"\" + this.query + \"\");\n item_description[index].innerHTML = description_text;\n item_title[index].innerHTML = title_text;\n }\n }\n },\n data: function data() {\n return {\n msg: 'Welcome to Your Vue.js App',\n query: this.parentQuery,\n\n page_select: 1,\n tips: '请输入要搜索的内容',\n show_button: false,\n response: []\n };\n },\n\n computed: {\n length: function length() {\n var len = 0;\n for (var item in this.response) {\n len++;\n }\n return len;\n },\n part_response: function part_response() {\n var part = [];\n for (var start = (this.page_select - 1) * 10; start < this.page_select * 10; start++) {\n if (start < this.length) {\n part.push(this.response[start]);\n }\n }\n\n var split_query = this.query.split(\"\");\n console.log(split_query);\n var char;\n var part_to_str = __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_json_stringify___default()(part);\n\n return part;\n }\n },\n methods: {\n submit: function submit() {\n var _this = this;\n\n this.tips = '正在查询。。。';\n var qs = __webpack_require__(47);\n\n this.$axios.post('./back_end.php', qs.stringify({\n 'question': this.query\n })).then(function (response) {\n _this.show_button = true;\n _this.response = response.data;\n\n _this.tips = '为您找到大约' + _this.length + '个结果';\n }).catch(function (error) {\n _this.tips = '查询失败,请检查网络连接';\n console.log(error);\n });\n }\n }\n});\n\n/***/ }),\n/* 35 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_vue__ = __webpack_require__(3);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__App__ = __webpack_require__(14);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__App___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__App__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__router__ = __webpack_require__(13);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_axios__ = __webpack_require__(12);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_axios___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_axios__);\n\n\n\n\n\n__WEBPACK_IMPORTED_MODULE_3_axios___default.a.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';\n__WEBPACK_IMPORTED_MODULE_0_vue__[\"a\" /* default */].prototype.$axios = __WEBPACK_IMPORTED_MODULE_3_axios___default.a;\n\n__WEBPACK_IMPORTED_MODULE_0_vue__[\"a\" /* default */].config.productionTip = false;\n\nnew __WEBPACK_IMPORTED_MODULE_0_vue__[\"a\" /* default */]({\n el: '#app',\n router: __WEBPACK_IMPORTED_MODULE_2__router__[\"a\" /* default */],\n template: '',\n components: { App: __WEBPACK_IMPORTED_MODULE_1__App___default.a }\n});\n\n/***/ }),\n/* 36 */,\n/* 37 */,\n/* 38 */,\n/* 39 */,\n/* 40 */,\n/* 41 */\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n/* 42 */\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n/* 43 */\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n/* 44 */,\n/* 45 */,\n/* 46 */,\n/* 47 */,\n/* 48 */,\n/* 49 */,\n/* 50 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\n/* styles */\n__webpack_require__(43)\n\nvar Component = __webpack_require__(2)(\n /* script */\n __webpack_require__(33),\n /* template */\n __webpack_require__(54),\n /* scopeId */\n \"data-v-e082b27e\",\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ }),\n/* 51 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\n/* styles */\n__webpack_require__(41)\n\nvar Component = __webpack_require__(2)(\n /* script */\n __webpack_require__(34),\n /* template */\n __webpack_require__(52),\n /* scopeId */\n \"data-v-17d40f1c\",\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ }),\n/* 52 */\n/***/ (function(module, exports) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n attrs: {\n \"id\": \"searchResult\"\n }\n }, [_c('div', {\n attrs: {\n \"id\": \"header\"\n }\n }, [_c('input', {\n directives: [{\n name: \"model\",\n rawName: \"v-model\",\n value: (_vm.query),\n expression: \"query\"\n }],\n attrs: {\n \"type\": \"text\",\n \"id\": \"input\"\n },\n domProps: {\n \"value\": (_vm.query)\n },\n on: {\n \"keyup\": function($event) {\n if (!('button' in $event) && _vm._k($event.keyCode, \"enter\", 13)) { return null; }\n _vm.submit($event)\n },\n \"input\": function($event) {\n if ($event.target.composing) { return; }\n _vm.query = $event.target.value\n }\n }\n }), _vm._v(\" \"), _c('button', {\n attrs: {\n \"id\": \"submit\"\n },\n on: {\n \"click\": _vm.submit\n }\n }, [_vm._v(\"search\")])]), _vm._v(\" \"), _c('div', {\n attrs: {\n \"id\": \"result\"\n }\n }, [_c('p', {\n attrs: {\n \"id\": \"result_number\"\n }\n }, [_vm._v(_vm._s(_vm.tips))]), _vm._v(\" \"), _vm._l((_vm.part_response), function(item) {\n return _c('div', [_c('a', {\n staticClass: \"item_title\",\n attrs: {\n \"id\": \"title\",\n \"href\": item.url,\n \"target\": \"_blank\"\n }\n }, [_vm._v(_vm._s(item.title))]), _vm._v(\" \"), _c('p', {\n staticClass: \"item_description\"\n }, [_vm._v(_vm._s(item.description))]), _vm._v(\" \"), _c('li', {\n attrs: {\n \"id\": \"small_url_content\"\n }\n }, [_c('a', {\n attrs: {\n \"href\": item.url,\n \"id\": \"small_url\",\n \"target\": \"_blank\"\n }\n }, [_vm._v(_vm._s(item.url))])]), _vm._v(\" \"), _c('li', {\n attrs: {\n \"id\": \"date\"\n }\n }, [_vm._v(\" \" + _vm._s(item.date))])])\n })], 2), _vm._v(\" \"), _c('div', {\n attrs: {\n \"id\": \"footer\"\n }\n }, _vm._l((parseInt(_vm.length / 10) + 1), function(n) {\n return (_vm.show_button) ? _c('button', {\n on: {\n \"click\": function($event) {\n _vm.page_select = n\n }\n }\n }, [_vm._v(_vm._s(n))]) : _vm._e()\n }))])\n},staticRenderFns: []}\n\n/***/ }),\n/* 53 */\n/***/ (function(module, exports) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n attrs: {\n \"id\": \"app\"\n }\n }, [_c('router-view', {\n attrs: {\n \"parent-query\": _vm.query\n },\n on: {\n \"childChange\": _vm.showResult\n }\n })], 1)\n},staticRenderFns: []}\n\n/***/ }),\n/* 54 */\n/***/ (function(module, exports) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n attrs: {\n \"id\": \"searchEngine\"\n }\n }, [_c('input', {\n directives: [{\n name: \"model\",\n rawName: \"v-model\",\n value: (_vm.query),\n expression: \"query\"\n }],\n attrs: {\n \"type\": \"text\",\n \"id\": \"text\"\n },\n domProps: {\n \"value\": (_vm.query)\n },\n on: {\n \"input\": [function($event) {\n if ($event.target.composing) { return; }\n _vm.query = $event.target.value\n }, _vm.change]\n }\n }), _vm._v(\" \"), _c('button', {\n attrs: {\n \"id\": \"button\"\n },\n on: {\n \"click\": _vm.submit\n }\n }, [_vm._v(\"search\")])])\n},staticRenderFns: []}\n\n/***/ })\n],[35]);\n\n\n// WEBPACK FOOTER //\n// static/js/app.2e2f3fd3b6a1a7409115.js","import Vue from 'vue'\nimport Router from 'vue-router'\nimport searchEngine from '@/components/searchEngine'\nimport searchResult from '@/components/searchResult'\n\nVue.use(Router)\n\nexport default new Router({\n routes: [\n {\n path: '/',\n name: 'searchEngine',\n component: searchEngine\n },\n {\n path: '/result',\n name: 'searchResult',\n component: searchResult\n }\n ]\n})\n\n\n\n// WEBPACK FOOTER //\n// ./src/router/index.js","\n/* styles */\nrequire(\"!!../node_modules/extract-text-webpack-plugin/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true}!vue-style-loader!css-loader?{\\\"minimize\\\":true,\\\"sourceMap\\\":true}!../node_modules/vue-loader/lib/style-compiler/index?{\\\"id\\\":\\\"data-v-3368385f\\\",\\\"scoped\\\":false,\\\"hasInlineConfig\\\":false}!../node_modules/vue-loader/lib/selector?type=styles&index=0!./App.vue\")\n\nvar Component = require(\"!../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n require(\"!!babel-loader!../node_modules/vue-loader/lib/selector?type=script&index=0!./App.vue\"),\n /* template */\n require(\"!!../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-3368385f\\\"}!../node_modules/vue-loader/lib/selector?type=template&index=0!./App.vue\"),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/App.vue\n// module id = 14\n// module chunks = 1","\n \n \n
\n\n\n\n\n\n\n\n\n// WEBPACK FOOTER //\n// App.vue?95b3cfb0","\n \n\t\t\n\t\t\n
\n\n\n\n\n\n\n\n\n\n// WEBPACK FOOTER //\n// searchEngine.vue?6023da28","\n\n\n\n\n\n\n\n\n\n\n\n// WEBPACK FOOTER //\n// searchResult.vue?4a96ffc2","// The Vue build version to load with the `import` command\n// (runtime-only or standalone) has been set in webpack.base.conf with an alias.\nimport Vue from 'vue'\nimport App from './App'\nimport router from './router'\nimport axios from 'axios'\naxios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';\nVue.prototype.$axios = axios\n\nVue.config.productionTip = false\n\n/* eslint-disable no-new */\nnew Vue({\n el: '#app',\n router,\n template: '',\n components: { App }\n})\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","\n/* styles */\nrequire(\"!!../../node_modules/extract-text-webpack-plugin/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true}!vue-style-loader!css-loader?{\\\"minimize\\\":true,\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"id\\\":\\\"data-v-e082b27e\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./searchEngine.vue\")\n\nvar Component = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n require(\"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./searchEngine.vue\"),\n /* template */\n require(\"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-e082b27e\\\"}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./searchEngine.vue\"),\n /* scopeId */\n \"data-v-e082b27e\",\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/searchEngine.vue\n// module id = 50\n// module chunks = 1","\n/* styles */\nrequire(\"!!../../node_modules/extract-text-webpack-plugin/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true}!vue-style-loader!css-loader?{\\\"minimize\\\":true,\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"id\\\":\\\"data-v-17d40f1c\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./searchResult.vue\")\n\nvar Component = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n require(\"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./searchResult.vue\"),\n /* template */\n require(\"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-17d40f1c\\\"}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./searchResult.vue\"),\n /* scopeId */\n \"data-v-17d40f1c\",\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/searchResult.vue\n// module id = 51\n// module chunks = 1","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n attrs: {\n \"id\": \"searchResult\"\n }\n }, [_c('div', {\n attrs: {\n \"id\": \"header\"\n }\n }, [_c('input', {\n directives: [{\n name: \"model\",\n rawName: \"v-model\",\n value: (_vm.query),\n expression: \"query\"\n }],\n attrs: {\n \"type\": \"text\",\n \"id\": \"input\"\n },\n domProps: {\n \"value\": (_vm.query)\n },\n on: {\n \"keyup\": function($event) {\n if (!('button' in $event) && _vm._k($event.keyCode, \"enter\", 13)) { return null; }\n _vm.submit($event)\n },\n \"input\": function($event) {\n if ($event.target.composing) { return; }\n _vm.query = $event.target.value\n }\n }\n }), _vm._v(\" \"), _c('button', {\n attrs: {\n \"id\": \"submit\"\n },\n on: {\n \"click\": _vm.submit\n }\n }, [_vm._v(\"search\")])]), _vm._v(\" \"), _c('div', {\n attrs: {\n \"id\": \"result\"\n }\n }, [_c('p', {\n attrs: {\n \"id\": \"result_number\"\n }\n }, [_vm._v(_vm._s(_vm.tips))]), _vm._v(\" \"), _vm._l((_vm.part_response), function(item) {\n return _c('div', [_c('a', {\n staticClass: \"item_title\",\n attrs: {\n \"id\": \"title\",\n \"href\": item.url,\n \"target\": \"_blank\"\n }\n }, [_vm._v(_vm._s(item.title))]), _vm._v(\" \"), _c('p', {\n staticClass: \"item_description\"\n }, [_vm._v(_vm._s(item.description))]), _vm._v(\" \"), _c('li', {\n attrs: {\n \"id\": \"small_url_content\"\n }\n }, [_c('a', {\n attrs: {\n \"href\": item.url,\n \"id\": \"small_url\",\n \"target\": \"_blank\"\n }\n }, [_vm._v(_vm._s(item.url))])]), _vm._v(\" \"), _c('li', {\n attrs: {\n \"id\": \"date\"\n }\n }, [_vm._v(\" \" + _vm._s(item.date))])])\n })], 2), _vm._v(\" \"), _c('div', {\n attrs: {\n \"id\": \"footer\"\n }\n }, _vm._l((parseInt(_vm.length / 10) + 1), function(n) {\n return (_vm.show_button) ? _c('button', {\n on: {\n \"click\": function($event) {\n _vm.page_select = n\n }\n }\n }, [_vm._v(_vm._s(n))]) : _vm._e()\n }))])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-17d40f1c\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/components/searchResult.vue\n// module id = 52\n// module chunks = 1","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n attrs: {\n \"id\": \"app\"\n }\n }, [_c('router-view', {\n attrs: {\n \"parent-query\": _vm.query\n },\n on: {\n \"childChange\": _vm.showResult\n }\n })], 1)\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-3368385f\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/App.vue\n// module id = 53\n// module chunks = 1","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n attrs: {\n \"id\": \"searchEngine\"\n }\n }, [_c('input', {\n directives: [{\n name: \"model\",\n rawName: \"v-model\",\n value: (_vm.query),\n expression: \"query\"\n }],\n attrs: {\n \"type\": \"text\",\n \"id\": \"text\"\n },\n domProps: {\n \"value\": (_vm.query)\n },\n on: {\n \"input\": [function($event) {\n if ($event.target.composing) { return; }\n _vm.query = $event.target.value\n }, _vm.change]\n }\n }), _vm._v(\" \"), _c('button', {\n attrs: {\n \"id\": \"button\"\n },\n on: {\n \"click\": _vm.submit\n }\n }, [_vm._v(\"search\")])])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-e082b27e\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/components/searchEngine.vue\n// module id = 54\n// module chunks = 1"],"sourceRoot":""}
--------------------------------------------------------------------------------
/dist/static/js/manifest.42e3257fe0dc6f03a838.js:
--------------------------------------------------------------------------------
1 | !function(e){function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var n=window.webpackJsonp;window.webpackJsonp=function(t,c,a){for(var i,u,f,s=0,l=[];s
2 |
3 |
4 |
5 | search-engine
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/jsonToMySQL.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import sys
3 | # reload(sys)
4 | # sys.setdefaultencoding('utf8')
5 |
6 | import json
7 | import codecs
8 | import MySQLdb
9 | def read():
10 | json_file = codecs.open("items.json", 'r', 'utf-8')
11 | data = json.load(json_file)
12 | return data
13 |
14 | def save(index_,url,description,date,title):
15 | try:
16 | db = MySQLdb.connect("localhost","root","666666","python",charset='utf8')
17 |
18 | data = (index_,url,description,date,title)
19 |
20 | cursor = db.cursor()
21 | except:
22 |
23 | print ("error")
24 |
25 | sql = "INSERT INTO `search_result` (`index_`, `url`, `description`, `date`, `title`) VALUES(%s,%s,%s,%s,%s)"
26 |
27 |
28 | try:
29 | cursor.execute(sql,data)
30 |
31 | db.commit()
32 | except:
33 | db.rollback()
34 |
35 | cursor.close()
36 |
37 | db.close()
38 | data = read()
39 | global index
40 | index = 400
41 | for line in data:
42 | #print line['description'][0]
43 | if(line['description'] and line['title']):
44 | save(index,line['url'],line['description'][0],'2017-04-15',line['title'][0])
45 | index +=1
46 | #print index
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "search-engine",
3 | "version": "1.0.0",
4 | "description": "a tiny search engine based on vue.js and use scrapy,jieba,php to accomplish it",
5 | "author": "xujingguo ",
6 | "private": true,
7 | "scripts": {
8 | "dev": "node build/dev-server.js",
9 | "start": "node build/dev-server.js",
10 | "build": "node build/build.js",
11 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
12 | "e2e": "node test/e2e/runner.js",
13 | "test": "npm run unit && npm run e2e"
14 | },
15 | "dependencies": {
16 | "vue": "^2.2.2",
17 | "vue-router": "^2.3.0"
18 | },
19 | "devDependencies": {
20 | "autoprefixer": "^6.7.2",
21 | "babel-core": "^6.22.1",
22 | "babel-loader": "^6.2.10",
23 | "babel-plugin-transform-runtime": "^6.22.0",
24 | "babel-preset-env": "^1.2.1",
25 | "babel-preset-stage-2": "^6.22.0",
26 | "babel-register": "^6.22.0",
27 | "chalk": "^1.1.3",
28 | "connect-history-api-fallback": "^1.3.0",
29 | "copy-webpack-plugin": "^4.0.1",
30 | "css-loader": "^0.26.1",
31 | "eventsource-polyfill": "^0.9.6",
32 | "express": "^4.14.1",
33 | "extract-text-webpack-plugin": "^2.0.0",
34 | "file-loader": "^0.10.0",
35 | "friendly-errors-webpack-plugin": "^1.1.3",
36 | "html-webpack-plugin": "^2.28.0",
37 | "http-proxy-middleware": "^0.17.3",
38 | "webpack-bundle-analyzer": "^2.2.1",
39 | "cross-env": "^3.1.4",
40 | "karma": "^1.4.1",
41 | "karma-coverage": "^1.1.1",
42 | "karma-mocha": "^1.3.0",
43 | "karma-phantomjs-launcher": "^1.0.2",
44 | "karma-phantomjs-shim": "^1.4.0",
45 | "karma-sinon-chai": "^1.2.4",
46 | "karma-sourcemap-loader": "^0.3.7",
47 | "karma-spec-reporter": "0.0.26",
48 | "karma-webpack": "^2.0.2",
49 | "lolex": "^1.5.2",
50 | "mocha": "^3.2.0",
51 | "chai": "^3.5.0",
52 | "sinon": "^2.1.0",
53 | "sinon-chai": "^2.8.0",
54 | "inject-loader": "^2.0.1",
55 | "babel-plugin-istanbul": "^3.1.2",
56 | "phantomjs-prebuilt": "^2.1.14",
57 | "chromedriver": "^2.27.2",
58 | "cross-spawn": "^5.0.1",
59 | "nightwatch": "^0.9.12",
60 | "selenium-server": "^3.0.1",
61 | "semver": "^5.3.0",
62 | "shelljs": "^0.7.6",
63 | "opn": "^4.0.2",
64 | "optimize-css-assets-webpack-plugin": "^1.3.0",
65 | "ora": "^1.1.0",
66 | "rimraf": "^2.6.0",
67 | "url-loader": "^0.5.8",
68 | "vue-loader": "^11.1.4",
69 | "vue-style-loader": "^2.0.0",
70 | "vue-template-compiler": "^2.2.4",
71 | "webpack": "^2.2.1",
72 | "webpack-dev-middleware": "^1.10.0",
73 | "webpack-hot-middleware": "^2.16.1",
74 | "webpack-merge": "^2.6.1"
75 | },
76 | "engines": {
77 | "node": ">= 4.0.0",
78 | "npm": ">= 3.0.0"
79 | },
80 | "browserslist": [
81 | "> 1%",
82 | "last 2 versions",
83 | "not ie <= 8"
84 | ]
85 | }
86 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
25 |
26 |
30 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xujingguo58/tinySearchEngine/8c8a7c5636b66c079ac835dbb5c6a20849b8447b/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/searchEngine.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
28 |
29 |
30 |
66 |
--------------------------------------------------------------------------------
/src/components/searchResult.vue:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
22 |
105 |
106 |
107 |
215 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 | import router from './router'
6 | import axios from 'axios'
7 | axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
8 | Vue.prototype.$axios = axios
9 |
10 | Vue.config.productionTip = false
11 |
12 | /* eslint-disable no-new */
13 | new Vue({
14 | el: '#app',
15 | router,
16 | template: '',
17 | components: { App }
18 | })
19 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import searchEngine from '@/components/searchEngine'
4 | import searchResult from '@/components/searchResult'
5 |
6 | Vue.use(Router)
7 |
8 | export default new Router({
9 | routes: [
10 | {
11 | path: '/',
12 | name: 'searchEngine',
13 | component: searchEngine
14 | },
15 | {
16 | path: '/result',
17 | name: 'searchResult',
18 | component: searchResult
19 | }
20 | ]
21 | })
22 |
--------------------------------------------------------------------------------
/test/e2e/custom-assertions/elementCount.js:
--------------------------------------------------------------------------------
1 | // A custom Nightwatch assertion.
2 | // the name of the method is the filename.
3 | // can be used in tests like this:
4 | //
5 | // browser.assert.elementCount(selector, count)
6 | //
7 | // for how to write custom assertions see
8 | // http://nightwatchjs.org/guide#writing-custom-assertions
9 | exports.assertion = function (selector, count) {
10 | this.message = 'Testing if element <' + selector + '> has count: ' + count
11 | this.expected = count
12 | this.pass = function (val) {
13 | return val === this.expected
14 | }
15 | this.value = function (res) {
16 | return res.value
17 | }
18 | this.command = function (cb) {
19 | var self = this
20 | return this.api.execute(function (selector) {
21 | return document.querySelectorAll(selector).length
22 | }, [selector], function (res) {
23 | cb.call(self, res)
24 | })
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/test/e2e/nightwatch.conf.js:
--------------------------------------------------------------------------------
1 | require('babel-register')
2 | var config = require('../../config')
3 |
4 | // http://nightwatchjs.org/gettingstarted#settings-file
5 | module.exports = {
6 | src_folders: ['test/e2e/specs'],
7 | output_folder: 'test/e2e/reports',
8 | custom_assertions_path: ['test/e2e/custom-assertions'],
9 |
10 | selenium: {
11 | start_process: true,
12 | server_path: require('selenium-server').path,
13 | host: '127.0.0.1',
14 | port: 4444,
15 | cli_args: {
16 | 'webdriver.chrome.driver': require('chromedriver').path
17 | }
18 | },
19 |
20 | test_settings: {
21 | default: {
22 | selenium_port: 4444,
23 | selenium_host: 'localhost',
24 | silent: true,
25 | globals: {
26 | devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
27 | }
28 | },
29 |
30 | chrome: {
31 | desiredCapabilities: {
32 | browserName: 'chrome',
33 | javascriptEnabled: true,
34 | acceptSslCerts: true
35 | }
36 | },
37 |
38 | firefox: {
39 | desiredCapabilities: {
40 | browserName: 'firefox',
41 | javascriptEnabled: true,
42 | acceptSslCerts: true
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/test/e2e/runner.js:
--------------------------------------------------------------------------------
1 | // 1. start the dev server using production config
2 | process.env.NODE_ENV = 'testing'
3 | var server = require('../../build/dev-server.js')
4 |
5 | server.ready.then(() => {
6 | // 2. run the nightwatch test suite against it
7 | // to run in additional browsers:
8 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings"
9 | // 2. add it to the --env flag below
10 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
11 | // For more information on Nightwatch's config file, see
12 | // http://nightwatchjs.org/guide#settings-file
13 | var opts = process.argv.slice(2)
14 | if (opts.indexOf('--config') === -1) {
15 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
16 | }
17 | if (opts.indexOf('--env') === -1) {
18 | opts = opts.concat(['--env', 'chrome'])
19 | }
20 |
21 | var spawn = require('cross-spawn')
22 | var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
23 |
24 | runner.on('exit', function (code) {
25 | server.close()
26 | process.exit(code)
27 | })
28 |
29 | runner.on('error', function (err) {
30 | server.close()
31 | throw err
32 | })
33 | })
34 |
--------------------------------------------------------------------------------
/test/e2e/specs/test.js:
--------------------------------------------------------------------------------
1 | // For authoring Nightwatch tests, see
2 | // http://nightwatchjs.org/guide#usage
3 |
4 | module.exports = {
5 | 'default e2e tests': function (browser) {
6 | // automatically uses dev Server port from /config.index.js
7 | // default: http://localhost:8080
8 | // see nightwatch.conf.js
9 | const devServer = browser.globals.devServerURL
10 |
11 | browser
12 | .url(devServer)
13 | .waitForElementVisible('#app', 5000)
14 | .assert.elementPresent('.hello')
15 | .assert.containsText('h1', 'Welcome to Your Vue.js App')
16 | .assert.elementCount('img', 1)
17 | .end()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/unit/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | Vue.config.productionTip = false
4 |
5 | // require all test files (files that ends with .spec.js)
6 | const testsContext = require.context('./specs', true, /\.spec$/)
7 | testsContext.keys().forEach(testsContext)
8 |
9 | // require all src files except main.js for coverage.
10 | // you can also change this to match only the subset of files that
11 | // you want coverage for.
12 | const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
13 | srcContext.keys().forEach(srcContext)
14 |
--------------------------------------------------------------------------------
/test/unit/karma.conf.js:
--------------------------------------------------------------------------------
1 | // This is a karma config file. For more details see
2 | // http://karma-runner.github.io/0.13/config/configuration-file.html
3 | // we are also using it with karma-webpack
4 | // https://github.com/webpack/karma-webpack
5 |
6 | var webpackConfig = require('../../build/webpack.test.conf')
7 |
8 | module.exports = function (config) {
9 | config.set({
10 | // to run in additional browsers:
11 | // 1. install corresponding karma launcher
12 | // http://karma-runner.github.io/0.13/config/browsers.html
13 | // 2. add it to the `browsers` array below.
14 | browsers: ['PhantomJS'],
15 | frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],
16 | reporters: ['spec', 'coverage'],
17 | files: ['./index.js'],
18 | preprocessors: {
19 | './index.js': ['webpack', 'sourcemap']
20 | },
21 | webpack: webpackConfig,
22 | webpackMiddleware: {
23 | noInfo: true
24 | },
25 | coverageReporter: {
26 | dir: './coverage',
27 | reporters: [
28 | { type: 'lcov', subdir: '.' },
29 | { type: 'text-summary' }
30 | ]
31 | }
32 | })
33 | }
34 |
--------------------------------------------------------------------------------
/test/unit/specs/Hello.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Hello from '@/components/Hello'
3 |
4 | describe('Hello.vue', () => {
5 | it('should render correct contents', () => {
6 | const Constructor = Vue.extend(Hello)
7 | const vm = new Constructor().$mount()
8 | expect(vm.$el.querySelector('.hello h1').textContent)
9 | .to.equal('Welcome to Your Vue.js App')
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/urlToKeywords.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import sys
3 | sys.path.append("../")
4 | import jieba
5 | import jieba.analyse
6 | import MySQLdb
7 |
8 |
9 | def save(index_,keywords,tf_idf):
10 | db = MySQLdb.connect("localhost","root","666666","python",charset='utf8')
11 |
12 | cursor = db.cursor()
13 |
14 | data = (index_,keywords,tf_idf)
15 |
16 | print tf_idf
17 |
18 | sql = "INSERT INTO `inverted index`(`index_`, `keywords`, `tf_idf`) VALUES(%s,%s,%s)"
19 |
20 |
21 | try:
22 | cursor.execute(sql,data)
23 |
24 | db.commit()
25 | except:
26 | print "error"
27 | db.rollback()
28 |
29 | cursor.close()
30 |
31 | db.close()
32 |
33 | def main():
34 | db = MySQLdb.connect("localhost","root","666666","python",charset='utf8')
35 |
36 | cursor = db.cursor()
37 |
38 | sql_query = "SELECT * FROM `search_result` WHERE 1"
39 |
40 |
41 | try:
42 | cursor.execute(sql_query)
43 |
44 | searchResult = cursor.fetchall()
45 |
46 | for row in searchResult:
47 | print row[0]
48 | seg_list = jieba.analyse.extract_tags(row[2],topK=30,withWeight=True)
49 | for line in seg_list:
50 | save(row[0],line[0], line[1])
51 | except:
52 | print "error"
53 | db.rollback()
54 |
55 | cursor.close()
56 |
57 | db.close()
58 | #seg_list = jieba.analyse.extract_tags(str2,topK=20,withWeight=True)
59 | #for line in seg_list:
60 | #save(line[0],line[1])
61 |
62 |
63 | if __name__=="__main__":
64 | main()
65 |
66 |
--------------------------------------------------------------------------------