62.1-爬蟲概述局蚀、Robots協(xié)議

好的生活就是不瞎想麦锯,做得多,要得少琅绅,常微笑懂知足!


總結:

  1. HTTP 是基于 socket 通訊的扶欣;是 異步請求;
  2. data參數(shù)決定是GET還是POST請求:為空采用GET方法千扶;不為空采用POST方法料祠;
  3. 對URL打包,對數(shù)據(jù)進行解析澎羞;

1. 概述

當今大數(shù)據(jù)的時代髓绽,網(wǎng)絡爬蟲已經(jīng)成為了獲取數(shù)據(jù)的一個重要手段。

爬蟲妆绞,應該稱為網(wǎng)絡爬蟲顺呕,也叫網(wǎng)頁蜘蛛、網(wǎng)絡機器人括饶、網(wǎng)絡螞蟻等株茶。
搜索引擎,就是網(wǎng)絡爬蟲的應用者巷帝。
為什么到了今天忌卤,反而這個詞匯被頻繁的提起呢?有搜索引擎不就夠了嗎楞泼?
實際上驰徊,大數(shù)據(jù)時代的到了,所有的企業(yè)都希望通過海量數(shù)據(jù)發(fā)現(xiàn)其中的價值堕阔。
所以棍厂,需要爬取對特定網(wǎng)站、特定類別的數(shù)據(jù)超陆,而搜索引擎不能提供這樣的功能牺弹,因此浦马,需要自己開發(fā)爬蟲來解
決。

2. 爬蟲分類

通用爬蟲

常見就是搜索引擎张漂,無差別的收集數(shù)據(jù)晶默、存儲,提取關鍵字航攒,構建索引庫磺陡,給用戶提供搜索接口。

爬取一般流程
1.初始一批URL漠畜, 將這些URL放到待爬取隊列
2.從隊列取出這些URL币他, 通過DNS解析IP, 對IP對應的站點下載HTML頁面憔狞, 保存到本地服務器中蝴悉, 爬取完的
URL放到已爬取隊列。
3.分析這些網(wǎng)頁內(nèi)容瘾敢, 找出網(wǎng)頁里面的其他關心的URL鏈接拍冠, 繼續(xù)執(zhí)行第2步, 直到爬取條件結束廉丽。

搜索引擎如何獲取一個新網(wǎng)站的URL
● 新網(wǎng)站主動提交給搜索引擎
● 通過其它網(wǎng)站頁面中設置的外鏈
● 搜索引擎和DNS服務商合作倦微, 獲取最新收錄的網(wǎng)站

聚焦爬蟲

有針對性的編寫特定領域數(shù)據(jù)的爬取程序,針對某些類別數(shù)據(jù)采集的爬蟲正压,是面向主題的爬蟲

3. Robots協(xié)議(原則)

指定一個robots.txt文件欣福,告訴爬蟲引擎什么可以爬取。

/ 表示網(wǎng)站根目錄焦履,表示網(wǎng)站所有目錄拓劝。
Allow 允許爬取的目錄
Disallow 禁止爬取的目錄
可以使用通配符

淘寶 http://www.taobao.com/robots.txt
馬蜂窩 http://www.mafengwo.cn/robots.txt

User-agent: Baiduspider
Allow: /article
Allow: /oshtml
Allow: /ershou
Disallow: /product/
Disallow: /

User-Agent: Googlebot
Allow: /article
Allow: /oshtml
Allow: /product
Allow: /spu
Allow: /dianpu
Allow: /oversea
Allow: /list
Allow: /ershou
Disallow: /

User-agent: Bingbot
Allow: /article
Allow: /oshtml
Allow: /product
Allow: /spu
Allow: /dianpu
Allow: /oversea
Allow: /list
Allow: /ershou
Disallow: /

User-agent: Baiduspider
Allow: /article
Allow: /oshtml
Allow: /ershou
Disallow: /product/
Disallow: /
其它爬蟲,不允許爬取
User-Agent: *
Disallow: /

這是一個君子協(xié)定嘉裤,“爬亦有道”

這個協(xié)議為了讓搜索引擎更有效率搜索自己內(nèi)容郑临,提供了如Sitemap這樣的文件。Sitemap往往是一個XML文件屑宠,
提供了網(wǎng)站想讓大家爬取的內(nèi)容的更新信息厢洞。
這個文件禁止抓取的往往又是可能我們感興趣的內(nèi)容,它反而泄露了這些地址典奉。

301躺翻,302

301,302 都是HTTP狀態(tài)的編碼卫玖,都代表著某個URL發(fā)生了轉移公你,不同之處在于:
301 redirect: 301 代表永久性轉移(Permanently Moved)。
302 redirect: 302 代表暫時性轉移(Temporarily Moved )假瞬。

4. HTTP請求和響應處理

其實爬取網(wǎng)頁就是通過HTTP協(xié)議訪問網(wǎng)頁陕靠,不過通過瀏覽器訪問往往是人的行為迂尝,把這種行為變成使用程序來訪問。

4.1 urllib包

urllib包(最老的爬蟲庫)
urllib是標準庫剪芥,它一個工具包模塊垄开,包含下面模塊來處理url:
urllib.request 用于打開和讀寫url
urllib.error 包含了由urllib.request引起的異常
urllib.parse 用于解析url
urllib.robotparser 分析robots.txt 文件

Python2中提供了urllib和urllib2。urllib提供較為底層的接口粗俱,urllib2對urllib進行了進一步封裝说榆。Python3中將
urllib合并到了urllib2中,并更名為標準庫urllib包寸认。

1. urllib.request模塊

模塊定義了在基本和摘要式身份驗證、 重定向串慰、 cookies等應用中打開 Url (主要是 HTTP) 的函數(shù)和類偏塞。

urlopen方法
urlopen(url, data=None)
url是鏈接地址字符串,或請求類的實例邦鲫。
data提交的數(shù)據(jù)灸叼,如果data為None發(fā)起GET請求,否則發(fā)起POST請求庆捺。見 urllib.request.Request#get_method
返回http.client.HTTPResponse類的響應對象古今,這是一個類文件對象。

from urllib import request
from http.client import HTTPResponse

url = "https://cn.bing.com/"  

response:HTTPResponse = request.urlopen(url)  # 類文件對象滔以;

with response:
    print(1,type(response))     # 類文件對象
    print(2,response.headers)  # 等價 info ()   #  
    print(2,response.info())  # 等價 info ()    # 
    print(3,response.geturl())
    print(4,response.status,response.reason)     
    print(5,response.read())            # 二進制的bytes對象
#------------------------------------------------------------------------------
C:\ProgramData\Miniconda3\envs\blog\python.exe C:/Users/dell/PycharmProjects/spiders/t1.py
1 <class 'http.client.HTTPResponse'>
2 Cache-Control: private, max-age=0
Content-Length: 111838
Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding
P3P: CP="NON UNI COM NAV STA LOC CURa DEVa PSAa PSDa OUR IND"
Set-Cookie: SRCHD=AF=NOFORM; domain=.bing.com; expires=Fri, 26-Aug-2022 02:43:09 GMT; path=/
Set-Cookie: SRCHUID=V=2&GUID=ECC0C843F1BA4EE7A8D5557520066A17&dmnchg=1; domain=.bing.com; expires=Fri, 26-Aug-2022 02:43:09 GMT; path=/
Set-Cookie: SRCHUSR=DOB=20200826; domain=.bing.com; expires=Fri, 26-Aug-2022 02:43:09 GMT; path=/
Set-Cookie: _SS=SID=2FDBF51342FC674231D5FA2143D266D4; domain=.bing.com; path=/
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-MSEdge-Ref: Ref A: 1E707EB1AAB64DB69C0FD272FD61B7BD Ref B: BJ1EDGE0221 Ref C: 2020-08-26T02:43:09Z
Set-Cookie: _EDGE_S=F=1&SID=2FDBF51342FC674231D5FA2143D266D4; path=/; httponly; domain=bing.com
Set-Cookie: _EDGE_V=1; path=/; httponly; expires=Mon, 20-Sep-2021 02:43:09 GMT; domain=bing.com
Set-Cookie: MUID=3AC183D8072E6AED16758CEA06006BDE; samesite=none; path=/; secure; expires=Mon, 20-Sep-2021 02:43:09 GMT; domain=bing.com
Set-Cookie: MUIDB=3AC183D8072E6AED16758CEA06006BDE; path=/; httponly; expires=Mon, 20-Sep-2021 02:43:09 GMT
Date: Wed, 26 Aug 2020 02:43:08 GMT
Connection: close

上例捉腥,通過urllib.request.urlopen方法,發(fā)起一個HTTP的GET請求你画,WEB服務器返回了網(wǎng)頁內(nèi)容抵碟。響應的數(shù)據(jù)被
封裝到類文件對象中,

通過read方法坏匪、readline方法拟逮、readlines方法獲取數(shù)據(jù),
status和reason屬性表示返回的狀態(tài)碼适滓,
info方法返回頭信息敦迄,

User-Agent問題
上例的代碼非常精簡,即可以獲得網(wǎng)站的響應數(shù)據(jù)凭迹。但目前urlopen方法通過url字符串和data發(fā)起HTTP的請求罚屋。
如果想修改HTTP頭,例如useragent蕊苗,就得借助其他方式沿后。

userAgent

源碼中構造的useragent如下

# urllib.request.OpenerDirector
class OpenerDirector:
def __init__(self):
client_version = "Python-urllib/%s" % __version__
self.addheaders = [('User-agent', client_version)]

當前顯示為 Python-urllib/3.6
有些網(wǎng)站是反爬蟲的,所以要把爬蟲偽裝成瀏覽器朽砰。隨便打開一個瀏覽器尖滚,復制瀏覽器的UA值喉刘,用來偽裝。

Request類

Request(url, data=None, headers={})
初始化方法漆弄,構造一個請求對象睦裳。可添加一個header的字典撼唾。data參數(shù)決定是GET還是POST請求廉邑。
add_header(key, val) 為header中增加一個鍵值對。

from urllib.request import Request, urlopen
import random
# 打開一個url返回一個Request請求對象
# url = 'https://movie.douban.com/' # 注意尾部的斜杠一定要有
url = 'http://www.bing.com/'

ua_list = [
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",# chrome
"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN) AppleWebKit/537.36 (KHTML, like Gecko) Version/5.0.1 Safari/537.36", # safafi
]

ua=random.choice(ua_list) #pick one
#ua需要加到請求頭中
request=Request(url)
request.add_header('User-Agent', random.choice(ua_list) )
print(type(request) )

response = urlopen(request, timeout=20) # request對象或者url都可以
print(type(response))

with response:
    print(1, response.status, response.getcode(), response.reason) # 狀態(tài)倒谷,getcode本質(zhì)上就是返回 status

    print(2, response.geturl()) # 返回數(shù)據(jù)的url蛛蒙。如果重定向,這個url和原始url不一樣
    # 例如原始url是http://www.bing.com/渤愁,返回http://cn.bing.com/
    print(3, response.info()) # 返回響應頭headers
    print(4, response.read()) # 讀取返回的內(nèi)容
print(5, request.get_header('User-agent'))
print(6, 'user-agent'.capitalize())
2.urllib.parse模塊

該模塊可以完成對url的編解碼; 先看一段代碼牵祟,進行編碼(默認UTF-8)

from urllib import parse
#  urlencode函數(shù)第一參數(shù)要求是一個字典或者二元組序列
u = parse.urlencode({'url':'http://www.magedu.com/python'})
print(u)
#---------------------------------------------------
url=http%3A%2F%2Fwww.magedu.com%2Fpython

/  %2F
=  3D


從運行結果來看冒號、斜杠抖格、&诺苹、等號、問號等符號全部被編碼了雹拄,%之后實際上是單字節(jié)十六進制表示的值收奔。

一般來說url中的地址部分,一般不需要使用中文路徑滓玖,但是參數(shù)部分坪哄,不管GET還是POST方法,提交的數(shù)據(jù)中呢撞,
可能有斜桿损姜、等號、問號等符號殊霞,這樣這些字符表示數(shù)據(jù)摧阅,不表示元字符。如果直接發(fā)給服務器端绷蹲,就會導致接收
方無法判斷誰是元字符棒卷,誰是數(shù)據(jù)了。

為了安全祝钢,一般會將數(shù)據(jù)部分的字符做url編碼比规,這樣就不會有歧義了。
后來可以傳送中文拦英,同樣會做編碼蜒什,一般先按照字符集的encoding要求轉換成字節(jié)序列,每一個字節(jié)對應的十六
進制字符串前加上百分號即可疤估。

# 網(wǎng)頁使用utf-8編碼
# https://www.baidu.com/s?wd=中
# 上面的url編碼后灾常,如下
# https://www.baidu.com/s?wd=%E4%B8%AD
from urllib import parse
u = parse.urlencode({'wd':'中'}) # 編碼
url = "https://www.baidu.com/s?{}".format(u)

print(url)
print('中'.encode('utf-8')) # b'\xe4\xb8\xad'
print(parse.unquote(u)) # 解碼
print(parse.unquote(url))
------------------------------------------------------
https://www.baidu.com/s?wd=%E4%B8%AD
b'\xe4\xb8\xad'
wd=中
https://www.baidu.com/s?wd=中
4.2 提交方法method

最常用的HTTP交互數(shù)據(jù)的方法是GET霎冯、POST。
GET方法钞瀑,數(shù)據(jù)是通過URL傳遞的沈撞,也就是說數(shù)據(jù)是在HTTP報文的header部分。
POST方法雕什,數(shù)據(jù)是放在HTTP報文的body部分提交的缠俺。
數(shù)據(jù)都是鍵值對形式,多個參數(shù)之間使用&符號連接贷岸。例如a=1&b=abc

from urllib import request,parse
from http.client import HTTPResponse

# ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"

base_url = "https://cn.bing.com/search"

u = parse.urlencode({'q':'馬哥教育'})
url = "{}?{}".format(base_url,u)

req = request.Request(url,headers={'User-agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"})

with request.urlopen(req) as response:
    with open('./bing.html','wb') as f:   #注意編碼壹士;
        f.write(response.read())
#-------------------------------------------------------

GET方法

連接 必應 搜索引擎官網(wǎng),獲取一個搜索的URL http://cn.bing.com/search?q=馬哥教育
需求 : 請寫程序完成對關鍵字的bing搜索偿警, 將返回的結果保存到一個網(wǎng)頁文件

from urllib import request,parse
from http.client import HTTPResponse

# ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"
# 請求什么返回什么
url = "http://httpbin.org/get"

req = request.Request(url,headers={'User-agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"})

with request.urlopen(req) as response:
    print(response.read())
#------------------------------------------------------------
b'{\n  "args": {}, \n  "headers": {\n    "Accept-Encoding": "identity", \n    "Host": "httpbin.org", \n    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", \n    "X-Amzn-Trace-Id": "Root=1-5f463de0-28f2bea1625061d03c4977d3"\n  }, \n  "origin": "117.150.188.202", \n  "url": "http://httpbin.org/get"\n}\n'

POST方法

http://httpbin.org/ 測試網(wǎng)站

from urllib import request,parse
from http.client import HTTPResponse

# ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"
# 請求什么返回什么
url = "http://httpbin.org/post"

req = request.Request(url,headers={'User-agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"})

params = parse.urlencode({
    'id':100,
    'name':'tommy'
})
with request.urlopen(req,params.encode()) as response:
    print(response.read())
#- --------------------------------------------------------------
b'{\n  "args": {}, \n  "headers": {\n    "Accept-Encoding": "identity", \n    "Host": "httpbin.org", \n    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", \n    "X-Amzn-Trace-Id": "Root=1-5f463de0-28f2bea1625061d03c4977d3"\n  }, \n  "origin": "117.150.188.202", \n  "url": "http://httpbin.org/get"\n}\n'
處理JSON數(shù)據(jù)

查看"豆瓣電影"墓卦,看到"最近熱門電影"的“熱門” ;

熱門

XHR : xml http request
tag 標簽“熱門”户敬,表示熱門電影
type 數(shù)據(jù)類型,movie是電影
page_limit 表示返回數(shù)據(jù)的總數(shù)
page_start 表示數(shù)據(jù)偏移

通過分析睁本,我們知道這部分內(nèi)容尿庐,是通過A JAX從后臺拿到的Json數(shù)據(jù)。
訪問URL是https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&page_limit=50&page_start=0%E7%83%AD%E9%97%A8
是utf-8編碼的中文“熱門” 服務器返回的Json數(shù)據(jù)50條

from urllib import request,parse
from http.client import HTTPResponse

# ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"
# 請求什么返回什么
url = "https://movie.douban.com/j/search_subjects"
params = parse.urlencode({
    'type':'movie',
    'tag':'熱門',
    'page_limit':3,
    'page_start':5,
})

url += '?' + params
req = request.Request(url,headers={'User-agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"})

with request.urlopen(req) as response:
    print(response.read())
-----------------------------------------------
b'{"subjects":[{"rate":"8.3","cover_x":5906,"title":"\xe5\xb0\x91\xe5\xb9\xb4\xe7\x9a\x84\xe4\xbd\xa0","url":"https:\\/\\/movie.douban.com\\/subject\\/30166972\\/","playable":true,"cover":"https://img3.doubanio.com\\/view\\/photo\\/s_ratio_poster\\/public\\/p2572166063.jpg","id":"30166972","cover_y":8268,"is_new":false},{"rate":"5.6","cover_x":1500,"title":"\xe8\xb6\x85\xe8\x83\xbd\xe8\xae\xa1\xe5\x88\x92","url":"https:\\/\\/movie.douban.com\\/subject\\/30330875\\/","playable":false,"cover":"https://img9.doubanio.com\\/view\\/photo\\/s_ratio_poster\\/public\\/p2614190404.jpg","id":"30330875","cover_y":2222,"is_new":false},{"rate":"6.2","cover_x":1080,"title":"\xe5\xa6\x99\xe5\x85\x88\xe7\x94\x9f","url":"https:\\/\\/movie.douban.com\\/subject\\/34888476\\/","playable":true,"cover":"https://img9.doubanio.com\\/view\\/photo\\/s_ratio_poster\\/public\\/p2614234255.jpg","id":"34888476","cover_y":1512,"is_new":false}]}'

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呢堰,一起剝皮案震驚了整個濱河市抄瑟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌枉疼,老刑警劉巖皮假,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異骂维,居然都是意外死亡惹资,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門航闺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來褪测,“玉大人,你說我怎么就攤上這事潦刃∥甏耄” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵乖杠,是天一觀的道長分扎。 經(jīng)常有香客問我,道長胧洒,這世上最難降的妖魔是什么畏吓? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任墨状,我火速辦了婚禮,結果婚禮上庵佣,老公的妹妹穿的比我還像新娘歉胶。我一直安慰自己,他們只是感情好巴粪,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布通今。 她就那樣靜靜地躺著,像睡著了一般肛根。 火紅的嫁衣襯著肌膚如雪辫塌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天派哲,我揣著相機與錄音臼氨,去河邊找鬼。 笑死芭届,一個胖子當著我的面吹牛储矩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播褂乍,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼持隧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了逃片?” 一聲冷哼從身側響起屡拨,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎褥实,沒想到半個月后呀狼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡损离,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年哥艇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片草冈。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡她奥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出怎棱,到底是詐尸還是另有隱情哩俭,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布拳恋,位于F島的核電站凡资,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜隙赁,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一垦藏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧伞访,春花似錦掂骏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至冒黑,卻和暖如春田绑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抡爹。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工掩驱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冬竟。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓欧穴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親泵殴。 傳聞我的和親對象是個殘疾皇子苔可,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344