node學(xué)習(xí)之路(一)—— 網(wǎng)絡(luò)請(qǐng)求

文章來源:小青年原創(chuàng)
發(fā)布時(shí)間:2016-09-29
關(guān)鍵詞:JavaScript,nodejs,http,url ,Query String,爬蟲
轉(zhuǎn)載需標(biāo)注本文原始地址: http://zhaomenghuan.github.io/#!/blog/20160929

前言

一直以來想深入學(xué)習(xí)一下node,一來是自己目前也沒有什么時(shí)間去學(xué)習(xí)服務(wù)器端語言,但是有時(shí)候又想自己擼一下服務(wù)器端,本著愛折騰的精神開始寫一寫關(guān)于node的文章記錄學(xué)習(xí)心得。本系列文章不會(huì)過多去講解node安裝、基本API等內(nèi)容,而是通過一些實(shí)例去總結(jié)常用用法。本文主要講解node網(wǎng)絡(luò)操作的相關(guān)內(nèi)容,node中的網(wǎng)絡(luò)操作依賴于http模塊,http模塊提供了兩種使用方式:

  • 作為服務(wù)器端使用,創(chuàng)建一個(gè)http服務(wù)器,監(jiān)聽http客戶端請(qǐng)求并返回響應(yīng);
  • 作為客戶端使用,發(fā)起一個(gè)http客戶端請(qǐng)求,獲取服務(wù)器端響應(yīng)。

node http模塊創(chuàng)建服務(wù)器

node 處理 get 請(qǐng)求實(shí)例

畢竟作為一個(gè)前端,我們經(jīng)常需要自己搭建一個(gè)服務(wù)器做測(cè)試,這里我們先來講一下node http模塊作為服務(wù)器端使用。首先我們需要,使用createServer創(chuàng)建一個(gè)服務(wù),然后通過listen監(jiān)聽客服端http請(qǐng)求。

我們可以創(chuàng)建一個(gè)最簡(jiǎn)單的服務(wù)器,在頁面輸出hello world,我們可以創(chuàng)建helloworld.js,內(nèi)容如下:

var http = require('http');

http.createServer(function(request, response){
    response.writeHead(200, { 'Content-Type': 'text-plain' });
    response.end('hello world!')
}).listen(8888);

在命令行輸入node helloworld.js即可,我們打開在瀏覽器打開http://127.0.0.1:8888/就可以看到頁面輸出hello world!。

下面我們?cè)诒镜貙懸粋€(gè)頁面,通過jsonp訪問我們創(chuàng)建的node服務(wù)器:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <div id="output"></div>
        
        <script type="text/javascript">
            // 創(chuàng)建script標(biāo)簽
            function importScript(src){
                var el = document.createElement('script');
                el.src = src;
                el.async = true;
                el.defer = true;
                document.body.appendChild(el);
            }
            
            // 響應(yīng)的方法
            function jsonpcallback(rs) {
                console.log(JSON.stringify(rs));
                document.getElementById("output").innerHTML = JSON.stringify(rs);
            }
            
            // 發(fā)起get請(qǐng)求
            importScript('http://127.0.0.1:8888?userid=xiaoqingnian&callback=jsonpcallback');
        </script>
    </body>
</html>

我們當(dāng)然需要將上述node服務(wù)器中的代碼稍作修改:

var http = require('http'); // 提供web服務(wù)
var url = require('url');   // 解析GET請(qǐng)求
  
var data = {
    'name': 'zhaomenghuan', 
    'age': '22'
};
  
http.createServer(function(req, res){  
    // 將url字符串轉(zhuǎn)換成Url對(duì)象
    var params = url.parse(req.url, true);  
    console.log(params);
    // 查詢參數(shù)
    if(params.query){
        // 根據(jù)附件條件查詢
        if(params.query.userid === 'xiaoqingnian'){
            // 判斷是否為jsonp方式請(qǐng)求,若是則使用jsonp方式,否則為普通web方式
            if (params.query.callback) {  
                var resurlt =  params.query.callback + '(' + JSON.stringify(data) + ')';
                res.end(resurlt);  
            } else {  
                res.end(JSON.stringify(data));
            }
        } 
    }      
}).listen(8888);

我們?cè)诿钚锌梢钥吹剑?/p>

Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: '?userid=xiaoqingnian&callback=jsonpcallback',
  query: { userid: 'xiaoqingnian', callback: 'jsonpcallback' },
  pathname: '/',
  path: '/?userid=xiaoqingnian&callback=jsonpcallback',
  href: '/?userid=xiaoqingnian&callback=jsonpcallback' }

經(jīng)過服務(wù)器端jsonp處理,然后返回一個(gè)函數(shù):

jsonpcallback({"name":"zhaomenghuan","age":"22"})

而我們?cè)陧撁嬷卸x了一個(gè)jsonpcallback()的方法,所以當(dāng)我們?cè)谡?qǐng)求頁面動(dòng)態(tài)生成script調(diào)用服務(wù)器地址,這樣相當(dāng)于在頁面執(zhí)行了下我們定義的函數(shù)。jsonp的實(shí)現(xiàn)原理主要是script標(biāo)簽src可以跨域執(zhí)行代碼,類似于你引用js庫(kù),然后調(diào)用這個(gè)js庫(kù)里面的方法;這是這里我們可以認(rèn)為反過來了,你是在本地定義函數(shù),調(diào)用的邏輯通過服務(wù)器返回的一個(gè)函數(shù)執(zhí)行了,所以jsonp并沒有什么神奇的,和XMLHttpRequest、ajax半毛錢關(guān)系都沒有,而且JSONP需要服務(wù)器端支持,始終是無狀態(tài)連接,不能獲悉連接狀態(tài)和錯(cuò)誤事件,而且只能走GET的形式。

node 處理 post 請(qǐng)求實(shí)例

當(dāng)然這里我們可以直接在后臺(tái)設(shè)置響應(yīng)頭進(jìn)行跨域(CORS),如:

var http = require("http"); // 提供web服務(wù)
var query = require("querystring"); // 解析POST請(qǐng)求

http.createServer(function(req,res){
    // 報(bào)頭添加Access-Control-Allow-Origin標(biāo)簽,值為特定的URL或"*"(表示允許所有域訪問當(dāng)前域)
    res.setHeader("Access-Control-Allow-Origin","*");
    
    var postdata = '';
    // 一旦監(jiān)聽器被添加,可讀流會(huì)觸發(fā) 'data' 事件
    req.addListener("data",function(chunk){
        postdata += chunk;
    })
    // 'end' 事件表明已經(jīng)得到了完整的 body
    req.addListener("end",function(){
        console.log(postdata);  // 'appid=xiaoqingnian'
        // 將接收到參數(shù)串轉(zhuǎn)換位為json對(duì)象
        var params = query.parse(postdata);
        if(params.userid == 'xiaoqingnian'){
            res.end('{"name":"zhaomenghuan","age":"22"}');
        }
    })
    
}).listen(8080);

我們通過流的形式接收前端post傳遞的參數(shù),通過監(jiān)聽data和end事件,后面在講解event模塊的時(shí)候再深入探究。

CORS默認(rèn)只支持GET/POST這兩種http請(qǐng)求類型,如果要開啟PUT/DELETE之類的方式,需要在服務(wù)端在添加一個(gè)"Access-Control-Allow-Methods"報(bào)頭標(biāo)簽:

res.setHeader(
    "Access-Control-Allow-Methods",
    "PUT, GET, POST, DELETE, HEAD, PATCH"
);

前端訪問代碼如下:

var xhr = new XMLHttpRequest();
xhr.onload = function () {
    console.log(this.responseText);
};
xhr.onreadystatechange = function() {
    console.log(this.readyState);
};

xhr.open("post", "http://127.0.0.1:8080", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("userid=xiaoqingnian");

url 模塊API詳解

url.parse——解析url字符串

上述代碼中比較關(guān)鍵的是我們通過url.parse方法將url字符串轉(zhuǎn)成Url對(duì)象,用法如下:

url.parse(urlStr, [parseQueryString], [slashesDenoteHost])

接收參數(shù):

  • urlStr:url字符串
  • parseQueryString:參數(shù)為true時(shí),query會(huì)被解析為JSON格式,否則為普通字符串格式,默認(rèn)為false;如:
    • 參數(shù)為true:query: { userid: 'xiaoqingnian', callback: 'jsonpcallback' }
    • 參數(shù)為false:query: 'userid=xiaoqingnian&callback=jsonpcallback'
  • slashesDenoteHost:默認(rèn)為false,當(dāng)url是 ‘http://’ 或 ‘ftp://’ 等標(biāo)志的協(xié)議前綴打頭的,或直接以地址打頭,如 ‘127.0.0.1’ 或 ‘localhost’ 時(shí)候是沒有區(qū)別的;當(dāng)且僅當(dāng)以2個(gè)斜杠打頭的時(shí)候,比如 ‘//127.0.0.1’ 才有區(qū)別。這時(shí)候,如果其值為true,則第一個(gè)單個(gè) ‘/’ 之前的部分被解析為 ‘host’ 和 ‘hostname’,如 ” host : ‘127.0.0.1’ “,如果為false,包括2個(gè)反斜杠在內(nèi)的所有字符串被解析為pathname。如:
> url.parse('//www.foo/bar',true,true)
Url {
  protocol: null,
  slashes: true,
  auth: null,
  host: 'www.foo',
  port: null,
  hostname: 'www.foo',
  hash: null,
  search: '',
  query: {},
  pathname: '/bar',
  path: '/bar',
  href: '//www.foo/bar' }
> url.parse('//www.foo/bar',true,false)
Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: '',
  query: {},
  pathname: '//www.foo/bar',
  path: '//www.foo/bar',
  href: '//www.foo/bar' }

這里的URL對(duì)象和瀏覽器中的location對(duì)象類似,location中如果我們需要使用類似的方法,我們需要自己構(gòu)造。

url.format——格式化URL對(duì)象

我們可以通過url.format方法將一個(gè)解析后的URL對(duì)象格式化成url字符串,用法為:

url.format(urlObj)

例子:

url.format({
  protocol: 'http:',
  slashes: true,
  auth: 'user:pass',
  host: 'host.com:8080',
  port: '8080',
  hostname: 'host.com',
  hash: '#hash',
  search: '?query=string',
  query: 'query=string',
  pathname: '/p/a/t/h',
  path: '/p/a/t/h?query=string',
  href: 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash' 
})

結(jié)果為:
'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

url.resolve——拼接url字符串

我們可以通過url.resolve為URL或 href 插入 或 替換原有的標(biāo)簽,接收參數(shù):
from源地址,to需要添加或替換的標(biāo)簽。

url.resolve(from, to)

例子為:

url.resolve('/one/two/three', 'four')
=> '/one/two/four'
url.resolve('http://example.com/', '/one')    
=> 'http://example.com/one'
url.resolve('http://example.com/one', '/two') 
=> 'http://example.com/two'

Query String 模塊Query String

querystring.escape——字符串編碼

querystring.escape('appkey=123&version=1.0.0+')
// 'appkey%3D123%26version%3D1.0.0%2B'

querystring.unescape——字符串解碼

querystring.unescape('appkey%3D123%26version%3D1.0.0%2B')
// 'appkey=123&version=1.0.0+'

querystring.stringify(querystring.encode)——序列化對(duì)象

querystring.stringify(obj[, sep][, eq][, options])
querystring.encode(obj[, sep][, eq][, options])

接收參數(shù)

  • obj: 欲轉(zhuǎn)換的對(duì)象
  • sep:設(shè)置分隔符,默認(rèn)為 ‘&'
  • eq:設(shè)置賦值符,默認(rèn)為 ‘='
querystring.stringify({foo: 'bar', baz: ['qux', 'quux'], corge: ''})
// 'foo=bar&baz=qux&baz=quux&corge='

querystring.stringify({foo: 'bar', baz: ['qux', 'quux'], corge: ''},',',':')
// 'foo:bar,baz:qux,baz:quux,corge:'

querystring.parse(querystring.decode)——解析query字符串

querystring.parse(str[, sep][, eq][, options])
querystring.decode(str[, sep][, eq][, options])

接收參數(shù)

  • str:欲轉(zhuǎn)換的字符串
  • sep:設(shè)置分隔符,默認(rèn)為 ‘&'
  • eq:設(shè)置賦值符,默認(rèn)為 ‘='
  • [options] maxKeys 可接受字符串的最大長(zhǎng)度,默認(rèn)為1000
querystring.parse('foo=bar&baz=qux&baz=quux&corge=')
// { foo: 'bar', baz: [ 'qux', 'quux' ], corge: '' }

querystring.parse('foo:bar,baz:qux,baz:quux,corge:',',',':')
{ foo: 'bar', baz: [ 'qux', 'quux' ], corge: '' }

node http模塊發(fā)起請(qǐng)求

平時(shí)喜歡看博客,畢竟買書要錢而且有時(shí)候沒有耐心讀完整本書,所以很喜歡逛一些網(wǎng)站,但是很多時(shí)候把所有的站逛一下又沒有那么多時(shí)間,哈哈,所以就準(zhǔn)備把常去的網(wǎng)站的文章爬出來做一個(gè)文章列表,一來省去收集的時(shí)間,二來借此熟悉熟悉node相關(guān)的東西。這里我們首先看一個(gè)爬蟲的小例子,下面以SF為例加以說明(希望不要被封號(hào))。

http.request與http.get的區(qū)別

http.request(options, callback)

options可以是一個(gè)對(duì)象或一個(gè)字符串。如果options是一個(gè)字符串, 它將自動(dòng)使用url.parse()解析。http.request() 返回一個(gè) http.ClientRequest類的實(shí)例。ClientRequest實(shí)例是一個(gè)可寫流對(duì)象。如果需要用POST請(qǐng)求上傳一個(gè)文件的話,就將其寫入到ClientRequest對(duì)象。使用http.request()方法時(shí)都必須總是調(diào)用req.end()以表明這個(gè)請(qǐng)求已經(jīng)完成,即使響應(yīng)body里沒有任何數(shù)據(jù)。如果在請(qǐng)求期間發(fā)生錯(cuò)誤(DNS解析、TCP級(jí)別的錯(cuò)誤或?qū)嶋HHTTP解析錯(cuò)誤),在返回的請(qǐng)求對(duì)象會(huì)觸發(fā)一個(gè)'error'事件。

Options配置說明:

  • host:請(qǐng)求發(fā)送到的服務(wù)器的域名或IP地址。默認(rèn)為'localhost'。
  • hostname:用于支持url.parse()。hostname比host更好一些
  • port:遠(yuǎn)程服務(wù)器的端口。默認(rèn)值為80。
  • localAddress:用于綁定網(wǎng)絡(luò)連接的本地接口。
  • socketPath:Unix域套接字(使用host:port或socketPath)
  • method:指定HTTP請(qǐng)求方法的字符串。默認(rèn)為'GET'。
  • path:請(qǐng)求路徑。默認(rèn)為'/'。如果有查詢字符串,則需要包含。例如'/index.html?page=12'。請(qǐng)求路徑包含非法字符時(shí)拋出異常。目前,只否決空格,不過在未來可能改變。
  • headers:包含請(qǐng)求頭的對(duì)象。
  • auth:用于計(jì)算認(rèn)證頭的基本認(rèn)證,即'user:password'
  • agent:控制Agent的行為。當(dāng)使用了一個(gè)Agent的時(shí)候,請(qǐng)求將默認(rèn)為Connection: keep-alive。可能的值為:
    • undefined(默認(rèn)):在這個(gè)主機(jī)和端口上使用[全局Agent][]。
    • Agent對(duì)象:在Agent中顯式使用passed。
    • false:在對(duì)Agent進(jìn)行資源池的時(shí)候,選擇停用連接,默認(rèn)請(qǐng)求為:Connection: close。
  • keepAlive:{Boolean} 保持資源池周圍的套接字在未來被用于其它請(qǐng)求。默認(rèn)值為false
  • keepAliveMsecs:{Integer} 當(dāng)使用HTTP KeepAlive的時(shí)候,通過正在保持活動(dòng)的套接字發(fā)送TCP KeepAlive包的頻繁程度。默認(rèn)值為1000。僅當(dāng)keepAlive被設(shè)置為true時(shí)才相關(guān)。

http.get(options, callback)

因?yàn)榇蟛糠值恼?qǐng)求是沒有報(bào)文體的GET請(qǐng)求,所以Node提供了這種便捷的方法。該方法與http.request()的唯一區(qū)別是它設(shè)置的是GET方法并自動(dòng)調(diào)用req.end()。

爬蟲實(shí)例

這里我們使用es6的新特性寫:

const https = require('https');
https.get('https://segmentfault.com/blogs', (res) => {
    console.log('statusCode: ', res.statusCode);
    console.log('headers: ', res.headers);
    var data = '';
    res.on('data', (chunk) => {
        data += chunk;
    });
    res.on('end', () => {
        console.log(data);
    })
}).on('error', (e) => {
    console.error(e);
});

這樣一小段代碼我們就可以拿到segmentfault的博客頁面的源碼,需要說明的是因?yàn)檫@里請(qǐng)求的網(wǎng)站是https協(xié)議,所以我們需要引入https模塊,用法同http一致。下面需要做的是解析html代碼,下面我們需要做的就是解析源碼,這里我們可以引入cheerio,一個(gè)node版的類jQuery模塊,npm地址:https://www.npmjs.com/package/cheerio

首先第一步安裝:

npm install cheerio

然后就是將html代碼load進(jìn)來,如下:

var cheerio = require('cheerio'),
var $ = cheerio.load(html);

最后我們就是分析dom結(jié)構(gòu)咯,通過類似于jQuery的方法獲取DOM元素的內(nèi)容,然后就將數(shù)據(jù)重新組裝成json結(jié)構(gòu)的數(shù)據(jù)。這里就是分析源碼然后,這里我就不詳細(xì)分析了,直接上代碼:

function htmlparser(html){
    var baseUrl = 'https://segmentfault.com';
    
    var $ = cheerio.load(html);
    var bloglist = $('.stream-list__item');
    
    var data = [];
    
    bloglist.each(function(item){
        var page = $(this);
        var summary = page.find('.summary');
        var blogrank = page.find('.blog-rank');
        
        var title = summary.find('.title a').text();
        var href = baseUrl + summary.find('.title a').attr('href');
        var author = summary.find('.author li a').first().text().trim();
        var origin = summary.find('.author li a').last().text().trim();
        var time = summary.find('.author li span')[0].nextSibling.data.trim();
        var excerpt = summary.find('p.excerpt').text().trim();
        var votes = blogrank.find('.votes').text().trim();
        var views = blogrank.find('.views').text().trim();
        
        data.push({
            title: title,
            href: href,
            author: author,
            origin: origin,
            time: time,
            votes: votes,
            views: views,
            excerpt: excerpt
        })
    })
    
    return data;
}

結(jié)果如下:

[{ title: '轉(zhuǎn)換流',
    href: 'https://segmentfault.com/a/1190000007036273',
    author: 'SwiftGG翻譯組',
    origin: 'SwiftGG翻譯組',
    time: '1 小時(shí)前',
    votes: '0推薦',
    views: '14瀏覽',
    excerpt: '作者:Erica Sadun,原文鏈接,原文日期:2016-08-29譯者:Darren;校對(duì):shank
s;定稿:千葉知風(fēng) 我在很多地方都表達(dá)了我對(duì)流的喜愛。我在 Swift Cookbook 中介紹了一些。現(xiàn)
在,我將通過 Pearson 的內(nèi)容更新計(jì)劃...' },
......
]

這里我們只是抓取了文章列表的一頁,如果需要抓取多頁,只需要將內(nèi)容再次封裝一下,傳入一個(gè)地址參數(shù)?page=2,如:https://segmentfault.com/blogs?page=2
另外我們也沒有將詳情頁進(jìn)一步爬蟲,畢竟文章的目的只是學(xué)習(xí),同時(shí)方便自己查看列表,這里保留原始地址。

溫馨提示:大家不要都拿sf做測(cè)試哦,不然玩壞了就不好。

模擬登陸

哈哈,寫到這里已經(jīng)很晚了,用node試了試模擬登陸SF,結(jié)果404,暫時(shí)沒有什么思路,等有時(shí)間再試試專門開篇講解咯。這里推薦一篇之前看到的文章:記一次用 NodeJs 實(shí)現(xiàn)模擬登錄的思路

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,494評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評(píng)論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,714評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,410評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,940評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,776評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,976評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,210評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評(píng)論 1 286
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,654評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,958評(píng)論 2 373

推薦閱讀更多精彩內(nèi)容