大师兄的Python学习笔记(三十): 爬虫(十一)

大师兄的Python学习笔记(二十九): 爬虫(十)
大师兄的Python学习笔记(三十一): 爬虫(十二)

十一、Scrapy框架

6. 关于Selector
  • Selector是Scrapy自己的选择器。
  • Selector基于lxml,支持xpath选择器、css选择器和正则表达式。
6.1 使用方法
  • 首先使用Selector模块创建一个选择器对象。
  • 使用.extract()获取内容列表,使用.extract_first()获取第一个匹配内容。

1) xpath选择器

  • xpath选择器使用selector.xpath()
  • 在xpath选择器中添加/text()选取文本内容。
  • 在xpath选择器中添加/@(<name>)选取属性。
>>>from scrapy import Selector

>>>html = '''
>>>    <html>
>>>        <head>
>>>            <title>
>>>                hello
>>>            </title>
>>>        </head>
>>>    </html>'''
>>>selector = Selector(text=html)
>>>title = selector.xpath('//title/text()').extract()
>>>print(title)
['\n                hello\n            ']

2) css选择器

  • css选择器使用selector.css()
  • 在选择器中添加::text选取文本内容。
  • 在选择器中添加::attr(<name>)选取某个属性。
>>>from scrapy import Selector

>>>html = '''
>>>    <html>
>>>        <head>
>>>            <title>
>>>                hello
>>>            </title>
>>>        </head>
>>>    </html>'''
>>>selector = Selector(text=html)
>>>title = selector.css('title::text').extract()
>>>print(title)
['\n                hello\n            ']

3) 正则匹配

  • 正则使用selector.re()匹配所有内容,或使用selector.re_first()匹配第一个内容。
>>>from scrapy import Selector

>>>html = '''
>>>    <html>
>>>        <head>
>>>            <title>
>>>                hello
>>>            </title>
>>>        </head>
>>>    </html>'''
>>>selector = Selector(text=html)
>>>title = selector.re('h.*o')
>>>print(title)
['hello']
  • 正则匹配还可以和选择器搭配使用
>>>from scrapy import Selector

>>>html = '''
>>>    <html>
>>>        <head>
>>>            <title>
>>>                hello
>>>            </title>
>>>        </head>
>>>    </html>'''
>>>selector = Selector(text=html)
>>>title = selector.css('title::text').re('e.*o')
>>>print(title)
['ello']
7. 关于Spider
  • 爬虫(Spider)模块负责定义爬取网站的动作,并分析爬取的网页。
7.1 爬虫的爬取流程

1) 以初始URL初始化Request,并设置回调函数parse(self, response)。请求成功后将response做为参数传给回调函数。

2) 在回调函数中分析网页内容,内容分两类:

  • 如果是有效结果,则返回Item或字典。
  • 如果是下一页,则用新的URL构造request并设置新的回调函数。

2-1) 如果返回结果,可通过Feed Exports等组件将返回结果存入文件,如果设置了Pipeline,则使用Pipeline处理并保存。

2-2) 如果返回下一页的请求,则根据请求结果并执行相应的回调函数, 解析并生成Item。
重复以上步骤,直到完成爬取。

7.2 scrapy.spiders.Spider类
  • Scrapy中所有的爬虫都必须继承scrapy.spiders.Spider类。
  • scrapy.spiders.Spider类包含以下属性和方法:
属性 介绍
name 爬虫的名称。
allowed_domains 允许爬取的域名白名单,可选。
start_urls 默认起始url列表,在没有实现start_requests()方法时从这里默认爬取。
custom_settings 爬虫的配置字典,会覆盖全局设置。
crawler 爬虫对应的Crawler对象,可以用来获取项目的配置信息settings
settings Settings对象,可以直接获取项目的全局设置变量。
方法 介绍
start_requests() 用于生成初始请求,默认使用start_urls里的URL构造请求,并返回一个可迭代对象。
parse() Response没有指定回调函数时被默认调用。
负责处理返回结果,并从中提取数据和下一步请求。
返回一个包含RequestItem的可迭代对象。
closed() 当爬虫被关闭时调用。
8. 关于Downloader Middleware
  • 即下载器中间件,负责处理引擎和下载器之间的请求(requet)和响应(response)。
  • 观察上图,下载器中间件在以下两个位置起作用:

1) 请求发送给下载器之前。

  • Scheduler -> Engine -> Downloader Middlewares-> Downloader

2) 响应发送给引擎->爬虫之前。

  • Downloader ->Downloader Middlewares-> Engine -> Spider
  • 下载器中间件的主要功能包括: 修改User-Agent、重定向、设置代理、失败重试、Cookies等。
8.1 核心方法
  • 下载器中间件有process_request(request,spider)process_response(request,response,spider)process_exception(request,exception,spider)三个核心方法,至少实现其中一个,即可定义一个下载器中间件。

1) process_request(request,spider)

  • 在请求发送给下载器之前调用。
  • 参数:
参数 说明
request 被处理的Request对象
spider 对应的爬虫对象
  • 返回值必须是None、Response对象、Request对象之一, 或抛出IgnoreRequest异常:
返回值 说明
None - 继续执行其他process_request()方法,直到下载器获得Response。
- 本质是根据优先级修改Request。
- 最后发送给Downloader执行。
Response对象 - 更低优先级的process_request()方法和process_exception()方法不会被继续调用。
- 每个process_response()方法转而被依次调用。
- 完成后将Response发送给爬虫处理。
Request对象 - 更低优先级的process_request()方法会停止执行。
- 这个Request会作为一个全新的Request放到调度队列里,等待调度。
- 被调度后,process_request()会被重新按照顺序执行。
抛出IgnoreRequest异常 - 所有的process_exception()方法依次执行。
如果异常没有被处理,则使用Request的errorback()方法回调。
如果异常还没有被处理,则忽略。

2) process_response(request,response,spider)

  • 在相应发送给爬虫之前调用。
  • 参数:
参数 说明
request Response对应的Request对象。
response 等待被处理的Response对象。
spider 对应的爬虫对象。
  • 返回值必须是Request对象、Response对象之一,或抛出IgnoreRequest异常。
返回值 说明
Request对象 - 更低优先级的process_response()方法不会继续调用。
- 这个Request会作为一个全新的Request放到调度队列里,等待调度。
- 被调度后,process_request()会被按照顺序执行。
Response对象 - 更低优先级的process_response()方法会继续调用,对该Response对象进行处理。
抛出IgnoreRequest异常 - Request的errorback()方法回调。
- 如果异常还没有被处理,则忽略。

3) process_exception(request,exception,spider)

  • 当下载器或process_request()方法抛出异常时被调用。
  • 参数:
参数 说明
request 产生异常的Request对象。
exception 被抛出的Exception对象。
spider 对应的爬虫对象。
  • 返回值必须是None、Response对象、Request对象之一。
参数 说明
None - 更低优先级的process_exception()会被继续按顺序调用,直到所有方法都被调度完毕。
Response对象 - 更低优先级的process_exception()不再被继续调用。
- process_response()方法装而被依次调用。
Request对象 - 更低优先级的process_exception()不再被继续调用。
- 这个Request会作为一个全新的Request放到调度队列里,等待调度。
- 被调度后,process_request()会被按照顺序执行。
  • 使用前需要在settings.py中配置中间件:
>>>DOWNLOADER_MIDDLEWARES = {
>>>   'project_sample.middlewares.ProjectSampleDownloaderMiddleware': 543,
>>>}
  • 一个简单案例,从settings中读取并修改request的user_agent:
>>>class ProjectSampleDownloaderMiddleware(object):
>>>    def __init__(self,user_agent):
>>>        self.user_agent=user_agent

>>>    @classmethod
>>>    def from_crawler(cls, crawler):
>>>        s = cls(crawler.settings['USER_AGENT'])
>>>        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
>>>        return s

>>>    def process_request(self, request, spider):
>>>        if self.user_agent:
>>>            request.headers.setdefault(b'User-Agent',self.user_agent)
>>>        return None

>>>    def spider_opened(self, spider):
>>>        self.user_agent = getattr(spider,'user_agent',self.user_agent)
9. 关于Spider Middleware
  • 即爬虫中间件,位于引擎和爬虫间的Hook框架,主要处理向爬虫输入的响应和输出的结果及新的请求。


  • 主要在以下三个位置起作用:

1) 下载器将生成的响应发送给爬虫之前

  • Downloader -> Engine -> Spider Middlewares -> Spiders

2) 爬虫将请求发送给Scheduler之前

  • Spider -> Spider Middlewares ->Engine -> Scheduler

3) 爬虫将生成的项目发给Item Pipeline之前
Spider -> Spider Middlewares ->Engine -> Item Pipeline

9.1 核心方法
  • 爬虫中间件的核心方法有:process_spider_input(response,spider)process_spider_output(response,result,spider)process_spider_exception(response,exception,spider)process_start_requests(start_requests,spider)

1) process_spider_input(response,spider)

  • 当爬虫中间件处理response时,该方法会被调用。
  • 参数:
参数 说明
response 将被处理的Response对象。
spider 对应的爬虫对象。
  • 返回值应该是None或者抛出异常:
返回值 说明
None 调用其它中间件,直到Spider处理这个Response。
抛出异常 - 不会调用其它的爬虫中间件,而是调用errback()方法。
- errback()的输出使用process_spider_output()方法处理。
- 异常调用process_spider_exception()处理。

2) process_spider_output(response,result,spider)

  • 当爬虫处理Response返回结果时调用。
  • 参数:
参数 说明
response 将被处理的Response对象。
result 爬虫的返回结果,包含Request或Item的可迭代对象。
spider 对应的爬虫对象。
  • 返回值是处理过的result,必须包含Request或item的可迭代对象。

3) process_spider_exception(response,exception,spider)

  • process_spider_input()抛出异常时调用。
  • 参数:
参数 说明
response 将被处理的Response对象。
exception 被抛出的Exception对象。
spider 对应的爬虫对象。
  • 返回值应该是None或者包含Response/Item的可迭代对象:
返回值 说明
None 继续调用其它process_spider_exception()方法,直到全部被调用。
Response/Item可迭代对象 调用process_spider_output()方法。

4) process_start_requests(start_requests,spider)

  • 当爬虫发起参数时被调用。
参数 说明
start_requests 包含Request的可迭代对象
spider 对应的爬虫对象。
  • 返回处理过的start_requests,也就是包含Request的可迭代对象。
  • 使用前需要先在settings.py配置中间件:
>>>SPIDER_MIDDLEWARES = {
>>>>   'project_sample.middlewares.ProjectSampleSpiderMiddleware': 543,
>>>}
  • 简单案例
class ProjectSampleSpiderMiddleware(object):
    def process_spider_output(self, response, result, spider):
        for i in result:
            if isinstance(i, scrapy.Item):
                print('现在将把Item发送到pipeline')
            yield i
... ...
现在将把Item发送到pipeline
2020-09-15 11:12:22 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/26357307/>
{'actors': 27,
 'director': '妮琪·卡罗',
 'title': '花木兰 Mulan',
 'url': 'https://movie.douban.com/subject/26357307/'}
... ...
10. 关于Item Pipeline
  • Item Pipeline即项目管道,接收并处理爬虫返回的Item(项目)。
  • Item Pipeline常用的操作有:

1) 清理HTML数据。
2) 验证爬取数据,检查爬取字段。
3) 查重并丢弃重复内容。
4) 将爬取结果保存到数据库。

10.1 使用Item Pipeline
  • Item Pipeline即项目管道,主要在爬虫流程的结尾部分生效:Spider -> Engine -> Item Pipeline
  • 使用Item Pipeline,必须在pipelines.py文件的类中添加一个process_item(item,spider)方法,除此之外还有open_spider(spider)close_spider(spider)from_crawler(cls,crawler)等方法。

1) process_item(item,spider)

  • 定义后的Item Pipeline会默认调用此方法。
  • 参数:
参数 说明
item 爬虫生成的Item对象。
spider 对应的爬虫。
  • 可以返回Item对象或抛出DropItem异常:
返回值 说明
Item对象 所有Item Pipeline按优先级继续处理。
抛出DropItem异常 Item对象被丢弃,不在进行处理。

2) open_spider(spider)

  • 在爬虫开启时被自动调用, 通常用来执行初始化工作。
  • 参数spider是相应的爬虫对象。

3) close_spider(spider)

  • 在爬虫关闭时被自动调用, 通常用来执行收尾工作。
  • 参数spider是相应的爬虫对象。

4) from_crawler(cls,crawler)

  • from_crawler()是类方法, 用@classmethod标识。
  • 类方法的第一个参数(cls)必须是类的实例。
  • 参数crawler是crawler对象,可以用于获得scrapy的全局配置信息。
  • 简单案例:
>>>from scrapy.exceptions import DropItem

>>>class ProjectSamplePipeline(object):
>>>    def process_item(self, item, spider):
>>>        # 将演员名称替换为演员数量
>>>        if item.get('actors'):
>>>            item['actors'] = len(item['actors'])
>>>            return item
>>>        else:
>>>            return DropItem("No actors")
  • 在使用前还需要在settings.py中配置item pipeline, 数字代表执行优先级权重:
>>># Configure item pipelines
>>># See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
>>>ITEM_PIPELINES = {
>>>   'project_sample.pipelines.ProjectSamplePipeline': 300,
>>>}
  • 运行爬虫查看结果,演员名称已经被替换为演员数:
D:\project_sample>scrapy crawl douban
... ...
{'actors': 18,
 'director': '泰特·泰勒',
 'title': '艾娃 Ava',
 'url': 'https://movie.douban.com/subject/30289869/'}
2020-09-10 09:56:46 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://movie.douban.com/subject/30129061/> (referer: https://movie.douban.com/chart)
2020-09-10 09:56:46 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://movie.douban.com/subject/27131969/> (referer: https://movie.douban.com/chart)
2020-09-10 09:56:46 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://movie.douban.com/subject/34462775/> (referer: https://movie.douban.com/chart)
2020-09-10 09:56:46 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/35141706/>
{'actors': 10,
 'director': '周润泽',
 'title': '东北往事:我叫刘海柱',
 'url': 'https://movie.douban.com/subject/35141706/'}
2020-09-10 09:56:46 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/30330875/>
{'actors': 27,
 'director': '亨利·朱斯特',
 'title': '超能计划 Project Power',
 'url': 'https://movie.douban.com/subject/30330875/'}
2020-09-10 09:56:47 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/30479644/>
{'actors': 27,
 'director': '杨宇硕',
 'title': '铁雨2:首脑峰会 강철비2: 정상회담',
 'url': 'https://movie.douban.com/subject/30479644/'}
2020-09-10 09:56:47 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/26389321/>
{'actors': 14,
 'director': '约什·布恩',
 'title': '新变种人 The New Mutants',
 'url': 'https://movie.douban.com/subject/26389321/'}
2020-09-10 09:56:47 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/30129061/>
{'actors': 15,
 'director': '查理·考夫曼',
 'title': "我想结束这一切 I'm Thinking of Ending Things",
 'url': 'https://movie.douban.com/subject/30129061/'}
2020-09-10 09:56:47 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/27131969/>
{'actors': 6,
 'director': '李云波',
 'title': '无名狂',
 'url': 'https://movie.douban.com/subject/27131969/'}
2020-09-10 09:56:47 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/34462775/>
{'actors': 2,
 'director': '赵一亨',
 'title': '#活着 #살아있다',
 'url': 'https://movie.douban.com/subject/34462775/'}
2020-09-10 09:56:47 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://movie.douban.com/subject/26357307/> (referer: https://movie.douban.com/chart)
2020-09-10 09:56:47 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://movie.douban.com/subject/30299515/> (referer: https://movie.douban.com/chart)
2020-09-10 09:56:47 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/26357307/>
{'actors': 27,
 'director': '妮琪·卡罗',
 'title': '花木兰 Mulan',
 'url': 'https://movie.douban.com/subject/26357307/'}
2020-09-10 09:56:47 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/30299515/>
{'actors': 8,
 'director': '延尚昊',
 'title': '釜山行2:半岛 부산행2-반도',
 'url': 'https://movie.douban.com/subject/30299515/'}
... ...
10.2 将数据保存到数据库
  • 首先需要在settings.py中配置Item pipeline和数据库信息。
>>># Configure item pipelines
>>># See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
>>>ITEM_PIPELINES = {
>>>   'project_sample.pipelines.ProjectSamplePipeline': 300,
>>>   'project_sample.pipelines.MongoDBPipeline': 400,
>>>}
>>>MONGO_URI='localhost'
>>>MONGO_DB='project'
  • pipelines.py文件中增加一个Item pipeline类:
>>>import pymongo

>>>class MongoDBPipeline(object):
>>>    def __init__(self,mongo_uri,mongo_db):
>>>        self.mongo_uri = mongo_uri
>>>        self.mongo_db = mongo_db

>>>    @classmethod
>>>    def from_crawler(cls,crawler):
>>>        # 类方法,用于获取settings中的全局的配置信息
>>>        return cls(
>>>            mongo_uri=crawler.settings.get('MONGO_URI'),
>>>            mongo_db=crawler.settings.get('MONGO_DB')
>>>        )

>>>    def open_spider(self,spider):
>>>        '''
>>>        spider开启时调用
>>>        用于初始化mongodb
>>>        '''
>>>        self.client = pymongo.MongoClient(self.mongo_uri)
>>>        self.db = self.client[self.mongo_db]

>>>    def close_spider(self,spider):
>>>        '''
>>>        spider结束时调用
>>>        用于关闭数据库链接
>>>        '''
>>>        self.client.close()

>>>    def process_item(self, item, spider):
>>>        name = item.__class__.__name__
>>>        self.db[name].insert(dict(item))
>>>        return item
  • 运行爬虫后,在数据库中查询:
> db.ProjectSampleItem.find()
{ "_id" : ObjectId("5f59929c69d6a3f8e7263087"), "url" : "https://movie.douban.com/subject/35141706/", "title" : "东北往事:我叫刘海柱", "actors" : 10, "director" : "周润泽" }
{ "_id" : ObjectId("5f59929c69d6a3f8e7263088"), "url" : "https://movie.douban.com/subject/34462775/", "title" : "#活着 #살아있다", "actors" : 2, "director" : "赵一亨" }
{ "_id" : ObjectId("5f59929c69d6a3f8e7263089"), "url" : "https://movie.douban.com/subject/30289869/", "title" : "艾娃 Ava", "actors" : 18, "director" : "泰特·泰勒" }
{ "_id" : ObjectId("5f59929c69d6a3f8e726308a"), "url" : "https://movie.douban.com/subject/26389321/", "title" : "新变种人 The New Mutants", "actors" : 14, "director" : "约什·布恩" }
{ "_id" : ObjectId("5f59929c69d6a3f8e726308b"), "url" : "https://movie.douban.com/subject/30330875/", "title" : "超能计划 Project Power", "actors" : 27, "director" : "亨利·朱斯特" }
{ "_id" : ObjectId("5f59929c69d6a3f8e726308c"), "url" : "https://movie.douban.com/subject/30479644/", "title" : "铁雨2:首脑峰会 강철비2: 정상회담", "actors" : 27, "director" : "杨宇硕" }
{ "_id" : ObjectId("5f59929c69d6a3f8e726308d"), "url" : "https://movie.douban.com/subject/27131969/", "title" : "无名狂", "actors" : 6, "director" : "李云波" }
{ "_id" : ObjectId("5f59929c69d6a3f8e726308e"), "url" : "https://movie.douban.com/subject/30129061/", "title" : "我想结束这一切 I'm Thinking of Ending Things", "actors" : 15, "director" : "查理·考夫曼" }
{ "_id" : ObjectId("5f59929d69d6a3f8e726308f"), "url" : "https://movie.douban.com/subject/30299515/", "title" : "釜山行2:半岛 부산행2-반도", "actors" : 8, "director" : "延尚昊" }
{ "_id" : ObjectId("5f59929d69d6a3f8e7263090"), "url" : "https://movie.douban.com/subject/26357307/", "title" : "花木兰 Mulan", "actors" : 27, "director" : "妮琪·卡罗" }
{ "_id" : ObjectId("5f5995018155a8757b4937eb"), "url" : "https://movie.douban.com/subject/30479644/", "title" : "铁雨2:首脑峰会 강철비2: 정상회담", "actors" : 27, "director" : "杨宇硕" }
{ "_id" : ObjectId("5f5995018155a8757b4937ec"), "url" : "https://movie.douban.com/subject/34462775/", "title" : "#活着 #살아있다", "actors" : 2, "director" : "赵一亨" }
{ "_id" : ObjectId("5f5995018155a8757b4937ed"), "url" : "https://movie.douban.com/subject/30330875/", "title" : "超能计划 Project Power", "actors" : 27, "director" : "亨利·朱斯特" }
{ "_id" : ObjectId("5f5995018155a8757b4937ee"), "url" : "https://movie.douban.com/subject/30129061/", "title" : "我想结束这一切 I'm Thinking of Ending Things", "actors" : 15, "director" : "查理·考夫曼" }
{ "_id" : ObjectId("5f5995018155a8757b4937ef"), "url" : "https://movie.douban.com/subject/27131969/", "title" : "无名狂", "actors" : 6, "director" : "李云波" }
{ "_id" : ObjectId("5f5995018155a8757b4937f0"), "url" : "https://movie.douban.com/subject/30289869/", "title" : "艾娃 Ava", "actors" : 18, "director" : "泰特·泰勒" }
{ "_id" : ObjectId("5f5995018155a8757b4937f1"), "url" : "https://movie.douban.com/subject/35141706/", "title" : "东北往事:我叫刘海柱", "actors" : 10, "director" : "周润泽" }
{ "_id" : ObjectId("5f5995018155a8757b4937f2"), "url" : "https://movie.douban.com/subject/26389321/", "title" : "新变种人 The New Mutants", "actors" : 14, "director" : "约什·布恩" }
{ "_id" : ObjectId("5f5995018155a8757b4937f3"), "url" : "https://movie.douban.com/subject/30299515/", "title" : "釜山行2:半岛 부산행2-반도", "actors" : 8, "director" : "延尚昊" }
{ "_id" : ObjectId("5f5995018155a8757b4937f4"), "url" : "https://movie.douban.com/subject/26357307/", "title" : "花木兰 Mulan", "actors" : 27, "director" : "妮琪·卡罗" }

参考资料



本文作者:大师兄(superkmi)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352