python八爬蟲框架

爬蟲框架

  1. BeautifulSoup
  2. 功能
    BeautifulSoup是用來從HTML或XML中提取數(shù)據(jù)的Python庫。
  3. 導(dǎo)入
  4. 使用方法:
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html)
  5. 對象種類
    有四種類型:Tag,NavigableString婿滓,BeautifulSoup色难,Comment肉瓦。
    BeautifulSoup將文檔轉(zhuǎn)化為樹形結(jié)構(gòu)梅忌,每個節(jié)點都是上述四種類型的Python對象嘲玫。
  • Tag
    與XML和HTML中Tag對象相同娇钱。
    如:
    soup = BeautifulSoup(<b class="boldest">Extremely bold</b>)
    soup.b就是一個Tag對象伤柄。
      1. Name
        tag.name 可獲取,可更改
      1. Attribute
        一個Tag對象可以有多個屬性文搂,操作方法和字典相同适刀,如上述Tag對象b就有一個class屬性:
        soup.b['class']
        或者使用get方法soup.b.get('class')
        獲取所有屬性鍵值對
        soup.b.attrs
        tag的屬性可添加、刪除(del soup.b['class'])煤蹭、修改笔喉,和字典方法相同。
        如果一個屬性key對應(yīng)多個value硝皂,則返回一個value的list常挚,如:
css_soup = BeautifulSoup('<p class="body strikeout" name="lzy"></p>') 
print css_soup.p.attrs
輸出:{'class': ['body', 'strikeout'], 'name': 'lzy'}

這種多個值的屬性是需要在HTML中有定義的,如果并沒有被定義為多值屬性吧彪,則返回字符串:

id_soup = BeautifulSoup('')
id_soup.p['id']
輸出'my id'

如果轉(zhuǎn)換的是XML文檔待侵,則不會存在多值屬性,返回字符串姨裸。
可以使用list或字符串對屬性賦值秧倾。

  • NavigableString
    Tag中的字符串即為NavigableString對象。
    tag.string
    在BeautifulSoup之外使用該類型傀缩,推薦轉(zhuǎn)換為Unicode:
    unicode(Tag.string)
    tag中包含的字符串不可編輯那先,只能替換
    tag.string.replace_with(new string)
    tag能夠包含其他tag或字符串,而NavigableString則不能包含其他對象赡艰。不支持.content售淡,.string,find()慷垮,只支持部分遍歷文檔樹和搜索文檔樹中的屬性揖闸。

  • BeautifulSoup
    表示的是一個文檔的全部內(nèi)容,大部分情況可當(dāng)做Tag對象料身,支持遍歷文檔樹和搜索文檔樹的大部分屬性汤纸。
    而在HTML或XML中并沒有叫做BeautifulSoup的Tag,所以并沒有name和attribute屬性芹血,但是有個特殊屬性:

soup.name
輸出u'[document]'
  • Comment
    Comment類型是NavigableString類型的子類贮泞,BeautifulSoup中也有同樣道理的一些其他類型楞慈。
<a class="sister"  id="link1"><!-- Elsie --></a>
 Elsie 
<class 'bs4.element.Comment'>

我們在使用前最好做一下判斷,判斷代碼如下

if type(soup.a.string)==bs4.element.Comment:
    print soup.a.string
  1. 遍歷文檔樹
    BeautifulSoup對象作為一棵樹啃擦,有多個節(jié)點囊蓝。對于一個節(jié)點,相對于它所在的位置令蛉,有子節(jié)點聚霜、父節(jié)點、兄弟節(jié)點言询。
  • 子節(jié)點
    一個Tag可包含多個Tag以及字符串俯萎,這些都是這個Tag的子節(jié)點傲宜。而NavigableString不會有子節(jié)點运杭。
    如果想要獲得某個Tag,上述已提到方法:
    soup.tag_name
    通過點取屬性函卒,只能獲得當(dāng)前名字的第一個tag辆憔,
    若要獲取所有,需要使用搜索文檔樹中的方法:
    soup.find_all('tag_name')
    tag的.contents屬性可將所有子節(jié)點以列表的方式輸出报嵌。
    可通過tag的.children生成器虱咧,對所有子節(jié)點進行遍歷。
    .contents和.children只對獲取Tag的直接子節(jié)點锚国,.descendants可用于對Tag的所有子孫節(jié)點進行遍歷腕巡。
    如果tag只有一個NavigableString類型子節(jié)點,則可用.string獲取血筑。如果包含多個绘沉,使用.strings遍歷。若輸出的字符串中包含空格或空行豺总,使用.stripped_strings去除车伞。
  • 父節(jié)點
    當(dāng)前節(jié)點的父節(jié)點:.parent
    當(dāng)前節(jié)點的所有父輩節(jié)點:.parents
  • 兄弟節(jié)點
    擁有同一父節(jié)點的節(jié)點之間。
    .next_sibling
    .previous_sibling
    同理喻喳,所有兄弟節(jié)點:
    .next_siblings
    .previous_siblings
    指向下一個或上一個解析對象:不區(qū)分層級
    .next_element
    .previous_element
    .next_elements
    .previous_elements
  1. 搜索文檔樹
    經(jīng)常使用的兩種方法: find(str)find_all(str)另玖。
    其中的str,代表了tag的name表伦∏ィ可以是純字符串、正則表達式蹦哼、列表(任一匹配就滿足條件鳄哭,是或運算)、True(返回所有Tag節(jié)點不返回字符串節(jié)點)翔怎。
    另一種入?yún)⒉皇莝tr窃诉,而是method杨耙。此方法是一個函數(shù),只接受一個元素入?yún)⑵矗舸撕瘮?shù)返回True表示入?yún)⑵ヅ湟笊耗ぁ@纾?/li>
def has_class_but_no_id(tag): 
return tag.has_attr('class') and not tag.has_attr('id')

綜上,過濾器包括:純字符串宣脉、正則表達式车柠、列表、True塑猖、方法這幾種竹祷。

  1. find_all(name,attrs,recursive,text,kwargs)
    該方法搜索
    當(dāng)前節(jié)點的所有tag子節(jié)點。**
- name參數(shù):

指的是tag的name屬性羊苟,字符串對象自動忽略塑陵。
過濾器可以使用全部種類。
- keyword參數(shù):
如果一個入?yún)⒅付嗣掷遣⒉皇巧鲜鎏岬降娜雲(yún)⒚至罨ǎ阉鲿r會把該入?yún)?dāng)做是tag的屬性來搜索。例如:
soup.find_all(id='link2')
會返回tag中存在屬性id凉倚,并且id對應(yīng)的值是link2的tag兼都。
以上方法可使用除方法之外的所有過濾器。
- 某些特殊屬性不能這樣直接使用稽寒,則使用如下方法:
soup.find_all(attrs={"key":"value"})
例如要使用class屬性進行搜索扮碧,由于class是python中的保留字,不能直接寫成入?yún)⑿硬冢壳坝袃煞N方法:

soup.find_all('tag.name',class_='class_value')
soup.find_all('tag.name',attrs={'class':'class_value'})

class_方法可以使用全部過濾器慎王。
另外,因為class是一個多值屬性搔啊,所以只需要匹配一個值柬祠,就可以得到結(jié)果,所謂的不完全匹配负芋。
使用完全匹配時漫蛔,過濾器中的字符順序需要和實際相符合才能得到對應(yīng)結(jié)果。
- text參數(shù):
搜索的是Tag中的字符串內(nèi)容旧蛾,可使用全部過濾器莽龟。
- limit參數(shù):
限制返回數(shù)量。
- recursive參數(shù):
find_all()默認(rèn)是搜索當(dāng)前節(jié)點的所有子孫節(jié)點锨天,若只需要搜索直接的子節(jié)點毯盈,則設(shè)置recursive=False

find_all()是實際當(dāng)中用的最廣泛的病袄。

因此有了等價的簡化版:

soup('a')```

  2. find(name,attrs,recursive,text,**kwargs)
find()方法等價于find_all(limit=1)搂赋,返回符合條件的第一個對象赘阀。
區(qū)別在于,前者直接返回結(jié)果脑奠,后者返回只有一個元素的列表基公。若沒有對象符合條件,前者返回None宋欺,后者返回空列表轰豆。
它也有簡化版:

soup.find('head').find('title')
soup.head.title

除了find()和find_all()之外還有一些搜索的方法:
find_parent()
find_next_sibling()
find_previous_sibling()
上面三種可以在后面加's'表示所有。
find_next()
find_previous()
find_all_next()
find_all_previous()

  3. CSS選擇器
Tag或BeautifulSoup對象的.select()方法齿诞。

7. **輸出**
prettify()將文檔樹格式化之后輸出酸休。
若不注重格式,則可使用python的str()或unicode()祷杈。
如果想得到tag中包含的文本內(nèi)容斑司,使用get_text(),可獲取到當(dāng)前節(jié)點的文本吠式,以及子孫節(jié)點中的文本陡厘。返回的是Unicode抽米。
可以指定參數(shù)設(shè)置分隔符如get_text("|")是以“|”作為分隔符特占。
get_text(strip=True)可去除文本前后的空白。
或者用.stripped_strings進行遍歷云茸。

7. **文檔解析器**
BeautifulSoup的第一個入?yún)⑹俏臋n是目,第二個入?yún)⑹俏臋n解析器,默認(rèn)情況下的優(yōu)先順序是:lxml标捺, html5lib懊纳,python標(biāo)準(zhǔn)庫。其中只有l(wèi)xml支持xml文檔的解析亡容。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嗤疯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子闺兢,更是在濱河造成了極大的恐慌茂缚,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屋谭,死亡現(xiàn)場離奇詭異脚囊,居然都是意外死亡,警方通過查閱死者的電腦和手機桐磁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門悔耘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人我擂,你說我怎么就攤上這事衬以』貉蓿” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵看峻,是天一觀的道長郎任。 經(jīng)常有香客問我,道長备籽,這世上最難降的妖魔是什么舶治? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮车猬,結(jié)果婚禮上霉猛,老公的妹妹穿的比我還像新娘。我一直安慰自己珠闰,他們只是感情好惜浅,可當(dāng)我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著伏嗜,像睡著了一般坛悉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上承绸,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天裸影,我揣著相機與錄音,去河邊找鬼军熏。 笑死轩猩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的荡澎。 我是一名探鬼主播均践,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼摩幔!你這毒婦竟也來了彤委?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤或衡,失蹤者是張志新(化名)和其女友劉穎焦影,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體薇宠,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡偷办,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了澄港。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椒涯。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖回梧,靈堂內(nèi)的尸體忽然破棺而出废岂,到底是詐尸還是另有隱情祖搓,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布湖苞,位于F島的核電站拯欧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏财骨。R本人自食惡果不足惜镐作,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望隆箩。 院中可真熱鬧该贾,春花似錦、人聲如沸捌臊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽理澎。三九已至逞力,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間糠爬,已是汗流浹背寇荧。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留秩铆,地道東北人砚亭。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像殴玛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子添祸,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,500評論 2 359

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