1. 程式人生 > >python 網站爬蟲 下載線上盜墓筆記小說到本地的指令碼

python 網站爬蟲 下載線上盜墓筆記小說到本地的指令碼

最近閒著沒事想看小說,找到一個全是南派三叔的小說的網站,決定都下載下來看看,於是動手,在很多QQ群裡高手的幫助下(本人正則表示式很爛,程式複雜的正則都是一些高手指導的),花了三四天寫了一個指令碼

需要 BeautifulSoup 和 requests 兩個庫

(我已經把註釋寫得儘量詳細)

這個程式的執行速度很慢,求高手告訴我優化的方法!!

#-*-coding:utf8-*-

from bs4 import BeautifulSoup
import requests
import re
import os


#開啟網頁將所需的URL讀取出來放進一個列表中
r = requests.get('http://www.nanpaisanshu.org/').content  #開啟要讀取的網頁
content=BeautifulSoup(r).findAll('a',href=re.compile(r'\Ahttp://www.nanpaisanshu.org/[a-z]+\Z')) #在網頁中找到需要的資訊

sc = str(content) #轉換為string型別

lists=[]
lists = sc.split(',')   
lists = list(set(lists)) #刪除列表中重複資訊

lisy=[]


for line in lists:
    p=line.split('"')[1]  #按 " 分割,取出需要的資訊寫進陣列
    lisy.append(p)        #這裡已經擁有需要的url
    #print p
#print lisy


#把讀取到的URL遍歷開啟,將所有網頁儲存到html檔案中

s = os.getcwd()#當前路徑

d = os.sep  #系統分隔符

namef='aaa' #檔案加名稱

#b = os.path.exists( s+d+namef) #判斷是存在

f=os.path.exists(s+d+namef) #判斷是存在

if f==False:
    os.mkdir(s+d+namef)  #如果資料夾不存在就新建一個
else:
    print u'已經存在'+namef

filenm = s+d+namef+d    #路徑

i=1
for line in lisy:
    r = requests.get(line)   #遍歷開啟所有url
    print r.content
    print '\n'
    tfile=open(filenm+'neirong'+str(i)+'.html','w')
    i=i+1
    tfile.write(r.content) #將網頁內容寫入檔案

#將URL檔案中的符合要求的URL讀取出來寫進一個txt檔案中
for i in range(1,len(lisy)+1):
    fp = open(filenm+'neirong'+str(i)+'.html', "r")
    of = open(filenm+'neirong'+str(i)+'.txt','w')  
    content = fp.read()   #將檔案內容讀取

    p=re.compile(r'http://www\.nanpaisanshu\.org/.*?\.html') #正則匹配
    
    #print p.findall(content)

    #print type(p.findall(content))

    for line in p.findall(content):  
        #print line+'\n'
        #if line !='http://www.nanpaisanshu.org/9701.html':
        of.write(line+'\n')  #將匹配到的檔案寫入另一個檔案中
        #else:
            #continue

        #of.write(str(p.findall(content)))

#關閉檔案
of.close()
fp.close()
tfile.close()


#將txt

for i in range(1,len(lisy)+1):
    ot=open(filenm+'neirong'+str(i)+'.txt','r')
    outfile=open(filenm+'quanbu'+str(i)+'.txt','a+')


    li=[]
    for line in ot:
        line = line.replace('\n','')
        li.append(line)   #將url檔案中的資料放進列表中

    li = sorted(li)  #給列表排序

    for line in li:
        print line
        #line = line.replace('\n','')
        r = requests.get(line).content  #遍歷開啟所有url
        title=BeautifulSoup(r).find("div",{'class':"post_title"}).h2   #取出標題
        content=BeautifulSoup(r).findAll("div",{'class':"post_entry"}) #取出內容
        sti=str(title).replace('<h2>','').replace('</h2>','')  #處理標題,只保留文字

        #處理內容,只保留文字
        scon = str(content).replace('<p>','  ').replace('</p>','  ').replace('<br/>','\n')
        #print str(urllist)
        scon = re.sub("<.*>", "", scon)
        scon = re.sub("(.*?);","",scon) 
        #scon = scon.strip()
        scon = '\n'.join(scon.split())

        print scon
        outfile.write(sti+'\n'+line+'\n'+scon) #將標題和內容寫進檔案中
    #i=i+1
    #print 
#print urllist

print '=========================下載結束======================='


#關閉檔案
outfile.close()
ot.close()



#取出指定資料夾下的所有檔名
targetDir=s+d+namef
for line in os.listdir(targetDir):

    p=re.compile(r'neirong[0-9]{1}') #用正則匹配
    if p.match(line)!=None:
        print "需要刪除的檔案"+s+d+namef+d+line+'!!'
        os.remove(s+d+namef+d+line)  #匹配成功就刪除這個檔案,os.remove()中需要完整路徑
    else:
        print '保留檔案!'
        continue  




有時候會顯示連線失敗,然後程式報錯,應該判斷一下  requests.get(url).status_code != 200  不過我加了以後發現執行更慢,每個頁面都判斷,汗,可能是因為我這裡網速幾K的原因才會異常

下面是修改後的完善版,慎用,速度極其的慢,判斷的東西和次數增加的緣故:

#-*-coding:utf8-*-

#下載盜墓筆記小說
#2014-10-14
#ZJL

from bs4 import BeautifulSoup
import requests
import re
import os


#開啟網頁將所需的URL讀取出來放進一個列表中
r = requests.get('http://www.nanpaisanshu.org/').content  #開啟要讀取的網頁
content=BeautifulSoup(r).findAll('a',href=re.compile(r'\Ahttp://www.nanpaisanshu.org/[a-z]+\Z')) #在網頁中找到需要的資訊

sc = str(content) #轉換為string型別

lists=[]
lists = sc.split(',')   
lists = list(set(lists)) #刪除列表中重複資訊

lisy=[]


for line in lists:
    p=line.split('"')[1]  #按 " 分割,取出需要的資訊寫進陣列
    lisy.append(p)        #這裡已經擁有需要的url
    #print p
#print lisy


#把讀取到的URL遍歷開啟,將所有網頁儲存到html檔案中

s = os.getcwd()#當前路徑

d = os.sep  #系統分隔符

namef='aaa' #檔案加名稱

#b = os.path.exists( s+d+namef) #判斷是存在

f=os.path.exists(s+d+namef) #判斷是存在

if f==False:
    os.mkdir(s+d+namef)  #如果資料夾不存在就新建一個
else:
    print u'已經存在'+namef

filenm = s+d+namef+d    #路徑

i=1
for line in lisy:
    r = requests.get(line)   #遍歷開啟所有url
    print r.content
    print '\n'
    tfile=open(filenm+'neirong'+str(i)+'.html','w')
    i=i+1
    tfile.write(r.content) #將網頁內容寫入檔案

#將URL檔案中的符合要求的URL讀取出來寫進一個txt檔案中
for i in range(1,len(lisy)+1):
    fp = open(filenm+'neirong'+str(i)+'.html', "r")
    of = open(filenm+'neirong'+str(i)+'.txt','w')  
    content = fp.read()   #將檔案內容讀取

    p=re.compile(r'http://www\.nanpaisanshu\.org/.*?\.html') #正則匹配
    
    #print p.findall(content)

    #print type(p.findall(content))

    for line in p.findall(content):  
        #print line+'\n'
        #if line !='http://www.nanpaisanshu.org/9701.html':
        of.write(line+'\n')  #將匹配到的檔案寫入另一個檔案中
        #else:
            #continue

        #of.write(str(p.findall(content)))

#關閉檔案
of.close()
fp.close()
tfile.close()


#將txt

for i in range(1,len(lisy)+1):
    ot=open(filenm+'neirong'+str(i)+'.txt','r')
    if os.path.exists(filenm+'quanbu'+str(i)+'.txt')==True:
        print "已經存在"+filenm+'quanbu'+str(i)+'.txt'+'會先刪除再建立'
        os.remove(filenm+'quanbu'+str(i)+'.txt')
        outfile=open(filenm+'quanbu'+str(i)+'.txt','a+')   #防止第二次下載時內容在檔案後面追加(不知道會不會重新新建檔案覆蓋掉原來的檔案所以這麼做)

    else:
        print "新建"+filenm+'quanbu'+str(i)+'.txt'
        outfile=open(filenm+'quanbu'+str(i)+'.txt','a+')


    
    li=[]
    for line in ot:
        line = line.replace('\n','')
        li.append(line)   #將url檔案中的資料放進列表中

    li = sorted(li)  #給列表排序

    for line in li:
    #print line
        #line = line.replace('\n','')

        if requests.get(line).status_code != 200:
            print '因為網路原因,這個章節為空!'
            outfile.write('因為網路原因,這個章節為空')   #判斷網路連線情況,防止連線失敗後程序報錯
        elif requests.get(line).status_code == 200:
            print '連線成功!'
            r = requests.get(line).content  #遍歷開啟所有url
            title=BeautifulSoup(r).find("div",{'class':"post_title"}).h2   #取出標題
            content=BeautifulSoup(r).findAll("div",{'class':"post_entry"}) #取出內容
            sti=str(title).replace('<h2>','').replace('</h2>','')  #處理標題,只保留文字

            #處理內容,只保留文字
            scon = str(content).replace('<p>','  ').replace('</p>','  ').replace('<br/>','\n')
            #print str(urllist)
            scon = re.sub("<.*>", "", scon)
            scon = re.sub("(.*?);","",scon) 
            #scon = scon.strip()
            scon = '\n'.join(scon.split())

            print scon
            outfile.write(sti+'\n'+line+'\n'+scon) #將標題,連結,內容寫進檔案中
        #i=i+1
        #print 
        #print urllist

print '=========================下載結束======================='


#關閉檔案
outfile.close()
ot.close()



#取出指定資料夾下的所有檔名
targetDir=s+d+namef
for line in os.listdir(targetDir):

    p=re.compile(r'neirong[0-9]{1}') #用正則匹配
    if p.match(line)!=None:
        print "需要刪除的檔案"+s+d+namef+d+line+'!!'
        os.remove(s+d+namef+d+line)  #匹配成功就刪除這個檔案,os.remove()中需要完整路徑
    else:
        print '保留檔案!'
        continue