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學的,無所謂,只需要去關注圖片怎樣儲存就可以了。
後面的一篇文章,我們實踐寫一個翻譯器,捎帶將幾個經常用到的功能點介紹下,讓大家基本可以爬到自己想要的東西。
再見。