整理思路:
首先觀察我們要爬取的頁面信息。如下:



自此我們獲得信息有如下:
♦1.小說名稱鏈接小說內容的一個url,url的形式是:http://www.365haoshu.com/Book/Chapter/ +href="detail.aspx?NovelId=3026&s=1527731727&t=DgV6NiFxdi8bOQ40DikZJQ0HCnYMBwZyDikgcA45BnAOKSB.&r=4298" #其中:&r=4298這個變化對小說章節順序沒有發生變化,你可以在后面改一下試一下
♦2.小說的鏈接和小說名稱都在同一個標簽下面。
至此我有了簡單的思路了:
根據以上條件特點我有了一個總體思路,我分別用兩個列表一個存放小說名字,一個存放列鏈接,然后然依次同時取出小說名字對應鏈接然后寫在一個文件里面。
♦1.根據難度性,我們先把所有的這個HTML內容響應出來放到一個類集合里面<class 'bs4.BeautifulSoup'>
♦2.再根據這個集合在檢索小說名字和鏈接所在所在的tag行,形成一個新的集合<class 'bs4.element.ResultSet'>
♦3.然后再在這個集合里面檢索小說名稱和小說鏈接,再形成一個新的類集合<class 'bs4.element.Tag'>
♦4.在檢索的同時就把這些檢索出來的東西分別存放在兩個字符串里面
♦5,按照順序依次遍歷出來並把對應小說的內用寫在text文件里面
我們需要用到的庫:
♦from bs4 import BeautifulSoup
♦import requests
小說章節鏈接:
♦http://www.365haoshu.com/Book/Chapter/List.aspx?NovelId=6686
♦小說名稱:為你傾心,為我傾城
接下來開始代碼部分:
from bs4 import BeautifulSoup#導入BeautifulSoup這個模塊爬蟲中很關鍵在第二篇中講
import requests #我們大概分三個步驟 #1.獲取章節和章節對應的鏈接信息 #2.獲取對應章節的內容 #3.把章節名字已經對應章節的內容寫進text文件里面
class spiderstory(object): def __init__(self): self.url = 'http://www.365haoshu.com/Book/Chapter/' self.names = []#存放章節名稱
self.hrefs = []#存放章節鏈接
def get_urlandname(self): response = requests.get(url=self.url + 'List.aspx?NovelId=6686 ')#回去章節目錄類型為<class 'requests.models.Response'>
req_parser = BeautifulSoup(response.text,"html.parser") # req后面跟text和html都行,固定寫法,BeautifulSoup默認支持Python的標准HTML解析庫數據類型:<class 'bs4.BeautifulSoup'>
# print(req_parser)
# print(type(req_parser))
div = req_parser.find_all('div',class_='user-catalog-ul-li') # 查找內容,標簽為div,屬性為class='user-catalog-ul-li',這里 是找到名字和鏈接所在的標簽,數據類型:<class 'bs4.element.ResultSet'>
# print(div)
# print(type(div))
a_bf = BeautifulSoup(str(div))#進行進一步的字符解析因為獲取要素類型的值時必須進行這一步
# print(type(a_bf))#<class 'bs4.BeautifulSoup'>
# print(len(a_bf))#1
a = a_bf.find_all('a') # # 查找內容,標簽為a#下面需要獲取a標簽下的href,所以這里首先要精確到a標簽下。才能從a標簽下獲取屬性的值
# print(len(a))
# print(a)
for i in a:#注意class類型和列表等一樣也是一個一個元素的,所以他可以用for遍歷,你可以用len查看一下
#print(i.find('span',class_='fl').string)#查找所有span和屬性class='fi'的字符類型的內容,注意因為class和類一樣了所寫成class_
# print(i)
# print(i['href'])
# print(type(i))
# print(len(i))
# print(i.find('span',class_='fl'))
self.names.append(i.find('span',class_='fl').string)#str只獲取指定的文本類型
#print(i.get('href'))#獲取有兩種方法:1.i.get('href' 2.i['href']
self.hrefs.append(self.url + i['href'])#注意如果TypeError: must be str, not NoneType,所以這里追加到字符串里面必須以字符的形式加
print(self.names) print(self.hrefs) def get_text(self,url): # print(self.hrefs[0])
respons2 =requests.get(url=url) # print(respons2)
c = BeautifulSoup(str(respons2.text),'html.parser') # print(c)
b = c.find_all('p', class_='p-content') text = [] for temp in b:#獲取標簽里面的文本只能進行遍歷每個滿足條件的文本才能獲取
text.append(temp.string) #b.string#獲取解析后的文本,獲取所有的文本類型
print(text) return text def writer(self,name,path,text1): ''' 寫入TXT文檔''' with open(path,'a',encoding='utf-8') as f: f.write(name + '\n')#寫入名字並換行
f.writelines(text1)#追加內容
f.write('\n\n')#換兩行
if __name__ == "__main__": # 運行入口
a= spiderstory() a.get_urlandname() # a.get_text()
for i in range(len(a.names)): name = a.names[i] text = str(a.get_text(a.hrefs[i]))#注意TypeError: write() argument must be str, not None,寫入文檔必須是字符串
a.writer(name,'F:\小說.txt',text) print(a)
以上是我寫的整體代碼以及一些調試的方法:
代碼整理如下:
from bs4 import BeautifulSoup import requests class spiderstory(object): def __init__(self): self.url = 'http://www.365haoshu.com/Book/Chapter/' self.names = []#存放章節名稱
self.hrefs = []#存放章節鏈接
def get_urlandname(self): '''獲取章節名稱和和章節URL''' response = requests.get(url=self.url + 'List.aspx?NovelId=6686 ') req_parser = BeautifulSoup(response.text,"html.parser") div = req_parser.find_all('div',class_='user-catalog-ul-li') a_bf = BeautifulSoup(str(div)) a = a_bf.find_all('a') for i in a: self.names.append(i.find('span',class_='fl').string) self.hrefs.append(self.url + i['href'])
def get_text(self,url): '''獲取對應章節內容''' respons2 =requests.get(url=url) c = BeautifulSoup(str(respons2.text),'html.parser') b = c.find_all('p', class_='p-content') text = [] for temp in b: text.append(temp.string) return text
def writer(self,name,path,text1): ''' 寫入TXT文檔''' with open(path,'a',encoding='utf-8') as f: f.write(name + '\n') f.writelines(text1) f.write('\n\n')
if __name__ == "__main__": # 運行入口
a= spiderstory() a.get_urlandname() for i in range(len(a.names)): name = a.names[i] text = str(a.get_text(a.hrefs[i])) a.writer(name,'F:\小說.txt',text) print(a)
