1. 程式人生 > >python手記(五):requests寫爬蟲(二):bs4處理文字資料

python手記(五):requests寫爬蟲(二):bs4處理文字資料

人生無趣且不易,一起找點樂子吧。歡迎評論,和文章無關的也可以。

 

 

 

上篇介紹了requests的基本用法,最後我們獲得了網頁的原始碼,並將其存到了文字中:

但是,我們需要的並不是全部的程式碼,我們需要的是文章的那一部分。其實requests.text返回的是字串型別,我們完全可以用字串處理,來獲得所需。But,太麻煩了,基於此,BeautifulSoup的出生就是來“解放生產力”的。

如果在命令視窗用pip命令的話,記得安裝的是bs4,而不是BeautifulSoup。

我們來簡單看下“靚湯”(好多地方這麼翻譯),是怎樣解放雙手的。

首先,生成bs物件:

from bs4 import BeautifulSoup

with open('spider.txt') as f:
    html = f.read()
bs = BeautifulSoup(html, 'html.parser')

將讀進來的字串直接讓bs吞掉,自己寫的時候當然沒這麼麻煩,requests.text獲得後,直接當引數傳遞給bs就可以了,第二個引數是解析器。對文字的解析方式,有三種:html.parser, lxml., html5lib。

有了物件,接下來就有趣了,就可以解放雙手了。(別亂想)

我們要獲得原始碼的title,    how?

print(bs.title)

That's all? Yeah, that's all.

除此之外,標籤還有一些屬性:

print(bs.title.name)#獲得標籤名稱
print(bs.title.attrs)#獲得標籤屬性,dict型別
print(bs.title.string)#獲得標籤之間的文字

結果:

由於我們選的這個標籤沒有屬性,所以attrs為空。我們換一個:

用這個link:

attrs就返回了href和rel屬性,有些時候我們需要獲得一些標籤的連結,就可以使用這種方法。

到這裡,就有了個問題,我們發現,這種方法只能返回它遇到的第一個標籤,如果我想要獲得所有的<a>標籤呢。

別急,還有個方法

bs = BeautifulSoup(html, 'html.parser')

bs = bs.find_all('a')
print(bs)

一個螢幕撐不下全部的<a>標籤。現在我們來看看我們需要的東西在哪裡:

在這,一個class="con news_content"的div標籤裡。

問題又來了,我們怎麼得到它呢,直接.div。不行,他不是第一個,find_all()也不行,我們不需要其他的div內容,只需要這個,那我們有沒有方法來限制標籤,我們要div標籤,其次,他的class是con news_content?

可以:

bs = bs.find('div', {'class':'con news_content' })

find方法,與findall的區別就是隻尋找一個,而不是全部,第二個引數用dict給出,來對bs加以限定。

由於東西太多,我們輸入到文字中再進行檢視:

bs = BeautifulSoup(html, 'html.parser')

bs = bs.find('div', {'class':'con news_content' })

txt = str(bs).replace(u'\xa0', u'')
with open('bs.txt', 'w') as f:
    f.write(txt)

中間有一步replace是文中的一個特殊字元,Unicode編碼的時候出了問題,將他刪掉了:

差不多了,有點意思了,但還是不好看,裡面還有很多標籤,怎麼處理?我們看到裡面的標籤近乎毫無規律,而且很密集,這時候我一般就要請正則表示式出場了,把整個文字進行匹配,匹配<.....>這樣的字串,然後用空字串去替換:

from bs4 import BeautifulSoup
import re

with open('spider.txt') as f:
    html = f.read()

bs = BeautifulSoup(html, 'html.parser')

bs = bs.find('div', {'class':'con news_content' })


txt = str(bs).replace(u'\xa0', u'')
dr = re.compile(r'<[^>]+>',re.S)
dd = dr.sub('',txt)#替換

with open('bs.txt', 'w') as f:
    f.write(dd)

正則表示式還是很強大的,當bs很難解放你的雙手的時候,那就勤勤懇懇的動手吧。

來看下效果:

Beautiful!

完成了,大家可以用這種方法,去爬自己想看的小說。不用擔心小說沒有在一個網頁上,其實他們都是有規律的,你檢視一本小說,第一話和第二話的url往往就是id=1,id=2的區別。你需要做的就是找到他的規律,有一個for迴圈,讓它一頁頁的幫你爬下來就可以了,很簡單吧。

舉個例子(網址我隨便編啦):

urlbase = 'http://www.xiaoshuo.com/daomu&id='

for i in range(100):
    url = urlbase + str(i)
    r = requests.get()
    bs = BeautifulSoup(r.text)
    ...
    ...

這樣就可以了。至於爬圖片,其實都是一樣的只是在把圖片寫入檔案的時候要用二進位制形式,而不能用文字形式:

https://blog.csdn.net/qq_41500251/article/details/80623877

這裡有個簡單例子,使用urllib學的,無所謂,只需要去關注圖片怎樣儲存就可以了。

後面的一篇文章,我們實踐寫一個翻譯器,捎帶將幾個經常用到的功能點介紹下,讓大家基本可以爬到自己想要的東西。

再見。