python3網絡爬蟲(抓取文字信息)

本文章是下文連接的學習筆記: 一小時入門python3網絡爬蟲
原文筆記是在winows下進行的,本文是在ubuntu下進行的全部操做.
爬蟲的大概思路其實就兩點:html

  • 獲取網頁的HTML信息
  • 解析HTML信息,提取咱們真正須要的內容

一 前言

二 網絡爬蟲簡介

1.審查元素

chrome:F12python

2.簡單實例

網絡爬蟲根據提供的URL信息,獲取網頁的HTML信息.
在Python\3中使用requesturllib.request來獲取網頁的具體信息.git

  • urllib庫Python內置,無需額外安裝
  • request是第三方庫,須要額外安裝 request庫的地址

(1)ubuntu安裝request:

sudo apt-get install python-requests

(2)簡單實例

/*
    構造一個請求,支撐如下各方法的基礎方法
*/
requests.request() 

/*獲取HTML網頁的主要方法,對應HTTP的GET*/
requests.get()

/*獲取HTML網頁頭信息的方法,對應於HTTP的HEAD*/
requests.head()

/*向HTML網頁提交POST請求的方法,對應於HTTP的POST*/
requests.post()

/*向HTML網頁提交PUT請求的方法,對應於HTTP的PUT*/
requests.put()

/*向HTML提交局部修改請求,對應於HTTP的PATCH*/
requests.patch()

/*向HTML頁面提交刪除請求,對應於HTTP的DELETE*/
requests.delete()

requests庫的使用教程
get請求的意思,顧名思義,就是從服務器獲取數據信息.下面是一個例子:github

#-*- coding:UTF-8 -*-
  2 import requests
  3 if __name__ == '__main__':
  4     target = 'http://gitbook.cn/'
  5     req = requests.get(url=target)  //req中保存了咱們獲取到信息
  6     print(req.text)

下面是執行上面的程序後抓取到的HTML信息: 左邊是程序抓取到的信息,右邊是網頁信息正則表達式

爬蟲實戰

1.小說下載

(1)實戰背景

目標網站:http://www.biqukan.com/
這是個小說網站.此次的目標是爬去並保存一本名爲"意念永恆"的小說.chrome

(2)小試牛刀

爬取"一念永恆"第一章的內容
將前面寫的代碼稍做修改運行就能夠了,以下:ubuntu

# -*- coding:UTF-8 -*-
    import requests

    if __name__ == '__main__':
        target = 'http://www.biqukan.com/1_1094/5403177.html'
        req = requests.get(url=target)
        print(req.text)

運行代碼,會發現獲得的是一堆帶有各類HTML標籤的小說內容.接下來的目標就是講小說的內容提取出來,過濾掉這些沒用的HTML標籤.服務器

(3)Beautiful Soup

提取咱們真正須要的內容有不少方法,例如用正則表達式,Xpath,Beautiful Soup等.這裏使用Beautifu Soup.
Beautiful Soup是一個第三方庫,這裏是中文學習文檔
beautiful soup 4的安裝方法:網絡

sudo apt-get install python-bs4

檢驗beautiful soup是否成功的方法:app

from bs4 import BeautifulSoup

觀察能夠看到,div\標籤中存放了小說的正文內容,因此如今的目標就是把div中的內容提取出來.
這裏div設置了兩個屬性classid.id是div的惟一標識,class規定元素的一個或多個類名.
提取小說正文內容的代碼以下:

# -*- coding:utf-8 -*-
  import requests
  from bs4 import BeautifulSoup
  
  if __name__ == '__main__':
      target = 'http://www.biqukan.com/1_1094/5403177.html'
      req = requests.get(url=target)
      html = req.text
      bf = BeautifulSoup(html,'lxml')
       ##使用find_all方法,獲取html信息中全部class屬性爲showtxt的div標籤
       ##find_all的第一個參數是獲取的標籤名,第二個參數class_是標籤屬性
       ##class在Python中是關鍵字,因此用class_標識class屬性,,避免衝突
      texts = bf.find_all('div',class_ = 'showtxt')
     ##decoude()是爲了將texts轉變成中文,若是不用這個方法,輸出的內容就是一堆編碼
    print(texts[0].decode())

輸入圖片說明
從圖片中能夠看出,此時的內容中還有一些其餘的HTML標籤,好比<br>
接下來就是要把這些不須要的字符去除,還有一些不須要的空格也刪除.代碼以下:

1 # -*- coding:utf-8 -*-
  2 import requests
  3 from bs4 import BeautifulSoup
  4 
  5 if __name__ == '__main__':
  6     target = 'http://www.biqukan.com/1_1094/5403177.html'
  7     req = requests.get(url=target)
  8     html = req.text
  9     bf = BeautifulSoup(html,'lxml')
 10      ##使用find_all方法,獲取html信息中全部class屬性爲showtxt的div標籤
 11      ##find_all的第一個參數是獲取的標籤名,第二個參數class_是標籤屬性
 12      ##class在Python中是關鍵字,因此用class_標識class屬性,,避免衝突
 13     texts = bf.find_all('div',class_ = 'showtxt')
 14     ##decoude()是爲了將texts轉變成中文,若是不用這個方法,輸出的內容就是一堆編碼
 15     print(texts[0].text.replace('\xa0'*8,'\n\n'))

運行代碼後,抓取效果以下: 抓取效果
在HTML中用"&nbsp"表示空格(記得後面加;號).上面代碼的最後一行的意思就是:
去掉文中的8個空格符號,並能用回車代替.
到目前爲止,咱們已經能夠抓取到小說一章的內容,而且進行了分段顯示.下一個目標就是要把整個小說都下載下來.
經過審查元素,咱們能夠看到,目標小說的全部章節標題都存在於<div class="listmain">標籤下.
具體章節又分別存在於<div>子標籤中的<dd><a></a></dd>標籤中. html中,標籤<a></a>用來存放超連接,連接地址存在於屬性href中.
審查元素
接下來,就是先抓取小說的目錄列表,代碼以下:

1 # -*- coding:utf-8 -*-
  2 import requests
  3 from bs4 import BeautifulSoup
  4 
  5 if __name__ == '__main__':
  6     target = 'http://www.biqukan.com/1_1094/'
  7     req = requests.get(url=target)
  8     html = req.text
  9     div_bf = BeautifulSoup(html)
 10     div = div_bf.find_all('div',class_="listmain")
 11     print(div[0])

抓取結果以下:
抓取章節標題
接下來,就是匹配抓取到的每個<a></a>標籤,並提取章節名和章節文章.例如,取第一章,標籤內容以下:

<a href="/1_1094/5403177.html">第一章 他叫白小純</a>

對BeautifulSoup返回的匹配結果a,使用a.get("href")方法,就能獲取href的屬性值,使用a.string就能獲取章節名,代碼以下:

1  -*- coding:utf-8 -*-
  2 import requests
  3 from bs4 import BeautifulSoup
  4 
  5 if __name__ == '__main__':
  6     server = 'http://www.biqukan.com'
  7     target = 'http://www.biqukan.com/1_1094/'
  8     req = requests.get(url=target)
  9     html = req.text
 10     div_bf = BeautifulSoup(html)
 11     div = div_bf.find_all('div',class_="listmain")
 12     a_bf = BeautifulSoup(str(div[0]))
 13     a=a_bf.find_all('a')
 14     for each in a:
 15         print(each.string,server+each.get('href'))

代碼執行結果:
抽取每一章節連接和標題
如今每一個章節的章節名,章節連接都有了.接下來就是整合代碼,將得到的內容寫入文本文件存儲就行了,代碼以下:

#-*-coding:utf-8-*-
  2 from bs4 import BeautifulSoup
  3 import requests,sys
  4 
  5 class downloader(object):
  6     def __init__(self):
  7         self.server = 'http://www.biqukan.com/'
  8         self.target = 'http://www.biqukan.com/1_1094/'
  9         self.names = [] #存放章節名
 10         self.urls = [] #存放章節連接
 11         self.nums = 0   #章節數
 12 
 13 #獲取下載地址
 14     def get_download_url(self):
 15         req = requests.get(url = self.target)
 16         html = req.text
 17         div_bf = BeautifulSoup(html)
 18         div = div_bf.find_all('div',class_='listmain')
 19         a_bf = BeautifulSoup(str(div[0]))
 20         a = a_bf.find_all('a')
 21         self.nums = len(a[15:])
 22         for each in a[15:]:
 23             self.names.append(each.string)
 24             self.urls.append(self.server+each.get('href'))
 25 
 26 #獲取章節內容
 27     def get_contents(self,target):
 28         req = requests.get(url =target)
 29         html = req.text
 30         bf = BeautifulSoup(html)
 31         texts = bf.find_all('div',class_='showtxt')
 32         texts = texts[0].text.replace('\xa0'*8,'\n\n')
 33         return texts
 34 
 35 #將抓取的文章內容寫入文件
 36     def writer(self,name,path,text):
 37         write_flag = True
 38         with open(path,'a',encoding='utf-8') as f:
 39             f.write(name+'\n')
 40             f.writelines(text)
 41             f.write('\n\n')
 42
 43 #主函數
 44 if __name__ == "__main__":
 45     dl = downloader()
 46     dl.get_download_url()
 47     print('<一年永恆>開始下載:')
 48     for i in range(dl.nums):
 49         dl.writer(dl.names[i],'一念永恆.txt',dl.get_contents(dl.urls[i]))
 50         sys.stdout.write("  已下載:%.3f%%"% float(i/dl.nums)+'\r')
 51         sys.stdout.flush()
 52     print('<一念永恆>下載完成')
相關文章
相關標籤/搜索