豆瓣讀書爬蟲(requests + re)
前面整理了一些爬蟲的內容,今天寫一個小小的栗子,內容不深,大佬請忽略。內容包括對豆瓣讀書網站中的書籍的基本資訊進行爬取,並整理,便於我們快速瞭解每本書的中心。
一、爬取資訊
每當爬取某個網頁的資訊時,首先就是要進入到網頁中,看看有沒有什麼爬取過程中的限制,可以檢視網站的robots協議。就是在原網址的後面加上"/robots.txt"。本網站中得到的結果是:
User-agent: * Disallow: /subject_search Disallow: /search Disallow: /new_subject Disallow: /service/iframe Disallow: /j/ Sitemap: http://www.douban.com/sitemap_index.xml Sitemap: http://www.douban.com/sitemap_updated_index.xml User-agent: Wandoujia Spider Disallow: /
根據上面的協議可以看到,並沒有禁止一些普通的爬蟲,就像我們現在這樣,僅僅爬取一點點的東西來供自己使用。那麼,我們就可以使用之前文章中提到的結構來實現這個爬蟲,首先匯入函式庫,然後套用框架,傳入地址,返回頁面內容。這點內容在這篇部落格中寫到了,這裡就不詳細解釋了。到此,網頁的爬取就結束了,接下來就剩下從這些東西中拿到我們想要的內容。
1 import requests 2 3 url = "https://book.douban.com/" 4 def getHtmlText(url): 5headers = { 6'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36' 7} 8try: 9response = requests.get(url, headers=headers) 10response.raise_for_status() 11response.encoding = response.apparent_encoding 12return response.text 13except: 14print("Fail") 15return 16 17 html = getHtmlText(url)
二、資訊處理
上面提取的的網頁程式碼包括很多東西,像展示出來的頁面的各種框架等等,這些對我們來說都是沒有用的,而且通過正則來提取資訊,如果在整個頁面中直接提取的話,不免會出現一些巧合,使得沒有提取到真正想要的內容,而且pattern一樣的其他內容,所以,首先,把要把關鍵的塊先拿出來,再一點一點的取出具體資訊。
1 import re 2 3 re_books = re.compile('<ul class="list-col list-col5 list-express slide-item">(.*?)</ul>', re.S)# re.S也在正則表示式的部落格中寫到了,是為了讓“.”可以匹配換行符 4 content = re_books.search(html)
通過檢查網頁原始碼,找到可以取出主要資訊的匹配規則,將中間的內容全部獲得。剩下的就是通過正則來提取每本書的每項資訊。這個在於自己觀察他們的規律,尋找匹配的規則。資訊的標籤不止一個,最後選擇了使用pandas來整理資料,pandas的DataFrame資料型別可以很方便的儲存二維結構,而且pandas有將資料之間儲存成excel格式的方法(DataFrame.to_excel())。
1 import pandas as pd# 這是大部分人的習慣,pandas比較長,而且在資料處理中經常使用,所以用pd兩個字母來代表 2 3 # 首先,先建立一個DataFrame,之後遍歷每本書籍的資訊,存成DataFrame格式拼接在他的後面就可以了 4 data = pd.DataFrame(columns=['title', 'author', 'abstract', 'href', 'publisher']) 5 6 re_book = re.compile('<li class="">(.*?)</li>', re.S) 7 bookList = re_book.findall(content[0])# findall找到所有的書籍資訊,返回為列表格式 8 for book in bookList: 9count = 0 10count += 1 11href = re.search('href="(.*?)"', book)# .*? 是指以非貪婪的模式匹配,()是分組,通過group方便取出其中的資訊 12href = href.group(1) 13title = re.search('<h4 class="title">(.*?)</h4>', book, re.S) 14title = title.group(1).split()[0] 15author = re.search('<span class="author">(.*?)</span>', book, re.S) 16author = ' '.join(author.group(1).split()) 17publisher = re.search('<span class="publisher">(.*?)</span>', book, re.S) 18publisher = ' '.join(publisher.group(1).split()) 19abstract = re.search('<p class="abstract">(.*?)</p>', book, re.S) 20abstract = ' '.join(abstract.group(1).split()) 21abstract = re.sub('【內容簡介】', '', abstract)# 慢慢除錯中發現,取得的資訊不太好看,其中在第一本數的主要內容開頭有這麼幾個字,就用re的sub方法替換掉了 22new = pd.DataFrame({"title":title, "author":author, "abstract":abstract, "href":href, "publisher":publisher}, index=["0"]) 23data = data.append(new, ignore_index=True) 24 data.to_excel('bookInfo.xls', encoding='utf-8')
我們可以看一下得到的結果,pandas直接輸出的結果也很規整,這裡儲存到了excel中,起初存到csv檔案中,但是亂碼了,後面沒多想就換成了excel,稍後我再去看看怎麼回事,或者有讀者清楚地,可以教教博主。
圖中有些東西沒有展示出來,但是大家都懂對吧。可以自己試一試。當然這個爬蟲很淺,僅得到這點的資料,後面的內容就交給你們了,可以試著往深裡點一點,原理都是大同小異的,學習爬蟲在平時就要隨時發現可以挖掘的東西,慢慢嘗試。