Python豆瓣書籍信息爬蟲


練習下BeautifulSoup,requests庫,用python3.3 寫了一個簡易的豆瓣小爬蟲,將爬取的信息在控制台輸出並且寫入文件中。

上源碼:

  1 # coding = utf-8
  2 '''my words
  3     基於python3 需要的庫 requests BeautifulSoup
  4     這個爬蟲很基本,沒有采用任何的爬蟲框架,用requests,BeautifulSoup,re等庫。
  5     這個爬蟲的基本功能是爬取豆瓣各個類型的書籍的信息:作者,出版社,豆瓣評分,評分人數,出版時間等信息。
  6     不能保證爬取到的信息都是正確的,可能有誤。
  7     也可以把爬取到的書籍信息存放在數據庫中,這里只是輸出到控制台。
  8     爬取到的信息存儲在文本txt中。
  9 '''
 10 
 11 import requests
 12 from bs4 import BeautifulSoup
 13 import re
 14 
 15 #爬取豆瓣所有的標簽分類頁面,並且提供每一個標簽頁面的URL
 16 def provide_url():
 17     # 以http的get方式請求豆瓣頁面(豆瓣的分類標簽頁面)
 18     responds = requests.get("https://book.douban.com/tag/?icn=index-nav")
 19     # html為獲得響應的頁面內容
 20     html = responds.text
 21     # 解析頁面
 22     soup = BeautifulSoup(html, "lxml")
 23     # 選取頁面中的需要的a標簽,從而提取出其中的所有鏈接
 24     book_table = soup.select("#content > div > .article > div > div > .tagCol > tbody > tr > td > a")
 25     # 新建一個列表來存放爬取到的所有鏈接
 26     book_url_list = []
 27     for book in book_table:
 28         book_url_list.append('https://book.douban.com/tag/' + str(book.string))
 29     return book_url_list
 30 
 31 #獲得評分人數的函數
 32 def get_person(person):
 33     person = person.get_text().split()[0]
 34     person = re.findall(r'[0-9]+',person)
 35     return person
 36 
 37 #當detail分為四段時候的獲得價格函數
 38 def get_rmb_price1(detail):
 39     price = detail.get_text().split('/',4)[-1].split()
 40     if re.match("USD", price[0]):
 41         price = float(price[1]) * 6
 42     elif re.match("CNY", price[0]):
 43         price = price[1]
 44     elif re.match("\A$", price[0]):
 45         price = float(price[1:len(price)]) * 6
 46     else:
 47         price = price[0]
 48     return price
 49 
 50 #當detail分為三段時候的獲得價格函數
 51 def get_rmb_price2(detail):
 52     price = detail.get_text().split('/',3)[-1].split()
 53     if re.match("USD", price[0]):
 54         price = float(price[1]) * 6
 55     elif re.match("CNY", price[0]):
 56         price = price[1]
 57     elif re.match("\A$", price[0]):
 58         price = float(price[1:len(price)]) * 6
 59     else:
 60         price = price[0]
 61     return price
 62 
 63 #測試輸出函數
 64 def test_print(name,author,intepretor,publish,time,price,score,person):
 65     print('name: ',name)
 66     print('author:', author)
 67     print('intepretor: ',intepretor)
 68     print('publish: ',publish)
 69     print('time: ',time)
 70     print('price: ',price)
 71     print('score: ',score)
 72     print('person: ',person)
 73 
 74 
 75 
 76 
 77 #解析每個頁面獲得其中需要信息的函數
 78 def get_url_content(url):
 79     res = requests.get(url)
 80     html = res.text
 81     soup = BeautifulSoup(html.encode('utf-8'),"lxml")
 82     tag = url.split("?")[0].split("/")[-1]  #頁面標簽,就是頁面鏈接中'tag/'后面的字符串
 83     titles = soup.select(".subject-list > .subject-item > .info > h2 > a") #包含書名的a標簽
 84     details = soup.select(".subject-list > .subject-item > .info > .pub") #包含書的作者,出版社等信息的div標簽
 85     scores = soup.select(".subject-list > .subject-item > .info > div > .rating_nums") #包含評分的span標簽
 86     persons = soup.select(".subject-list > .subject-item > .info > div > .pl")  #包含評價人數的span標簽
 87 
 88     print("*******************這是 %s 類的書籍**********************" %tag)
 89 
 90     #打開文件,將信息寫入文件
 91     file = open("C:/Users/lenovo/Desktop/book_info.txt",'a') #可以更改為你自己的文件地址
 92     file.write("*******************這是 %s 類的書籍**********************" % tag)
 93 
 94     #用zip函數將相應的信息以元祖的形式組織在一起,以供后面遍歷
 95     for title,detail,score,person in zip(titles,details,scores,persons):
 96         try:#detail可以分成四段
 97             name = title.get_text().split()[0] #書名
 98             author = detail.get_text().split('/',4)[0].split()[0] #作者
 99             intepretor = detail.get_text().split('/',4)[1] #譯者
100             publish = detail.get_text().split('/',4)[2]  #出版社
101             time = detail.get_text().split('/',4)[3].split()[0].split('-')[0] #出版年份,只輸出年
102             price = get_rmb_price1(detail)   #獲取價格
103             score = score.get_text() if True else ""   #如果沒有評分就置空
104             person = get_person(person)  #獲得評分人數
105             #在控制台測試打印
106             test_print(name,author,intepretor,publish,time,price,score,person)
107             #將書籍信息寫入txt文件
108             try:
109                 file.write('name: %s ' % name)
110                 file.write('author: %s ' % author)
111                 file.write('intepretor: %s ' % intepretor)
112                 file.write('publish: %s ' % publish)
113                 file.write('time: %s ' % time)
114                 file.write('price: %s ' % price)
115                 file.write('score: %s ' % score)
116                 file.write('person: %s ' % person)
117                 file.write('\n')
118             except (IndentationError,UnicodeEncodeError):
119                 continue
120 
121         except IndexError:
122             try:#detail可以分成三段
123                 name = title.get_text().split()[0]  # 書名
124                 author = detail.get_text().split('/', 3)[0].split()[0]  # 作者
125                 intepretor = "" # 譯者
126                 publish = detail.get_text().split('/', 3)[1]  # 出版社
127                 time = detail.get_text().split('/', 3)[2].split()[0].split('-')[0]  # 出版年份,只輸出年
128                 price = get_rmb_price2(detail)  # 獲取價格
129                 score = score.get_text() if True else ""  # 如果沒有評分就置空
130                 person = get_person(person)  # 獲得評分人數
131                 #在控制台測試打印
132                 test_print(name, author, intepretor, publish, time, price, score, person)
133                 #將書籍信息寫入txt文件
134                 try:
135                     file.write('name: %s ' % name)
136                     file.write('author: %s ' % author)
137                     file.write('intepretor: %s ' % intepretor)
138                     file.write('publish: %s ' % publish)
139                     file.write('time: %s ' % time)
140                     file.write('price: %s ' % price)
141                     file.write('score: %s ' % score)
142                     file.write('person: %s ' % person)
143                     file.write('\n')
144                 except (IndentationError, UnicodeEncodeError):
145                     continue
146 
147             except (IndexError,TypeError):
148                 continue
149 
150         except TypeError:
151             continue
152     file
153 
154     file.write('\n')
155     file.close()  #關閉文件
156 
157 
158 #程序執行入口
159 if __name__ == '__main__':
160     #url = "https://book.douban.com/tag/程序"
161     book_url_list = provide_url() #存放豆瓣所有分類標簽頁URL的列表
162     for url in book_url_list:
163         get_url_content(url)  #解析每一個URL的內容

下面是效果圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM