python 上個小爬蟲的改進
阿新 • • 發佈:2018-11-29
上一篇寫的是個爬取古詩詞網上的古詩,並寫到檔案裡,今天做了一下改進。
1、之前寫的是網頁上顯示的摺疊詩,就是詩的內容是摺疊的,內容短的話可能是詩的全部,如果長的話只是一部分了,所以這裡做出改進,讓它爬取連結處的內容,因為如果你點選連線後會顯示詩的全部內容。
體會:首先你要自己分析好頁面在進行爬取。
2、 改進了容錯性,可能點選連結會失效,這裡失效後就爬去下一條內容而非報錯終止。
以下為程式碼:(ps 重點是分析頁面,每個頁面有自己的結構,找到共性就好)
編碼問題也是個大問題,具體問題具體解決吧。#-*- coding:gbk -*- import urllib.request import time,os import numpy as np from bs4 import BeautifulSoup hds=[{'User-Agent': 'Mozilla/5.0 (Windows; U;Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}, \ {'User-Agent': 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11'}, \ {'User-Agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)'}] def search(value,page): url='http://so.gushiwen.org/search.aspx?type=author&page='+urllib.request.quote(str(page))+'&value='+urllib.request.quote(value) #拼接url使用urllib.request.quote()把漢字和數字拼接到url裡 time.sleep(np.random.rand() * 2)#隨機等一段時間再進行訪問 try: req=urllib.request.Request(url,headers=hds[page%3]) html_resource=urllib.request.urlopen(req) # print(html_resource.info()) 輸出伺服器資訊 plain_text=html_resource.read().decode() return plain_text except (urllib.request.HTTPError,urllib.request.URLError) as e: print(e) def rmline(str): #這是一個去除字串中的空行的函式 data='' for line in str: l=line.strip() if len(l)!=0: data+=l return data def getpoemMessage(poem_id,page): url = 'http://so.gushiwen.org/shiwen/ajaxshiwen.aspx?id=' + poem_id + '&from=search' print(url) time.sleep(np.random.rand() * 1) # 隨機等一段時間再進行訪問 try: req=urllib.request.Request(url,headers=hds[page%3]) html_resource=urllib.request.urlopen(req) # print(html_resource.info()) 輸出伺服器資訊 plain_text=html_resource.read().decode() return plain_text except (urllib.request.HTTPError,urllib.request.URLError) as e: print(e) def parse_poem(html): soup=BeautifulSoup(html,'lxml') if (soup.find('title')): pass else: poem_title = soup.p poem_title_str = poem_title.a.string poem_author = poem_title.next_sibling.next_sibling poem_author_str = poem_author.string.split(u'\xa0')[0] # 注意gbk無法識別u'\xa0'編碼,他的意思為空格 poem_text = list(soup.div.next_sibling.next_sibling.strings) poem_text_str = '' for text in list(soup.div.next_sibling.next_sibling.strings)[6:-2]: poem_text_str += text + '\n' with open('poem2.txt', mode='a', encoding='utf-8') as f: f.write('題目: ' + rmline(poem_title_str) + '\n') f.write(poem_author_str + '\n') f.write('內容: ' + poem_text_str + '\n') f.write('-----------------------------------------' + '\n') def parseHtml(html,page): # soup=BeautifulSoup(html,'lxml') # title=soup.title#獲取網頁title # title_name=title.name#獲取title的名字 也就是標籤的名字 # title_string=title.string#獲取title的值 # title_parent=soup.title.parent#title的父物件 # # soup.p#獲取第一個p標籤 # soup.p['class']#獲取第一個p標籤裡面的class值 # # soup.find_all('a')#找到所有的a標籤 # soup.find(id='***')#獲取id為***的標籤 soup=BeautifulSoup(html,'lxml') with open('poem2.txt',mode='a',encoding='utf-8') as f: f.write('第'+str(page)+'頁'+'\n') if page==1: for poem in soup.find_all("div", "sons")[1:]: print(poem['id']) id=poem['id'][11:] parse_poem(getpoemMessage(id,page)) else: for poem in soup.find_all("div", "sons"): print(poem['id']) id = poem['id'][11:] parse_poem(getpoemMessage(id, page)) if __name__=="__main__": filename = 'poem2.txt' if os.path.exists(filename): os.remove(filename) for page in range(1,3): #1,4是指頁數,也就是下載前三頁資料。下面的作者名字可以隨意改,或者寫詩的名字也可以 parseHtml(search('納蘭性德',page), page)