python爬蟲實例之慢速VOA網站的文章爬取(第二次實戰,還是有意義的)

python爬蟲實例之慢速VOA網站的文章爬取

程序的需求分析
  • 爬取前兩頁所有文章的名字
  • 將文章的名字按照需要輸出在控制檯
  • 同時將每一篇文章保存在對應的以文章名爲題的文檔中
前期分析
  • 首先來看看你的網頁的概況,網址是:https://www.51voa.com/Technology_Report_1.html

  • 這是首頁
    在這裏插入圖片描述

  • 再看看對應的網頁原碼

所有的文章名稱都是在"< a >…<\a>"標籤中的,並且這個a標籤不同於別的a標籤,都有target屬性,並且所有的target屬性都是“_blank”,故直接通過對應查找標籤的findall函數直接查找所有的標籤,直接獲取標籤的string值

<a href="/VOA_Special_English/how-effective-are-online-symptom-checkers-84580.html" target=_blank>How Effective Are Online Symptom Checkers?</a>


<a href="/VOA_Special_English/coronavirus-crisis-changes-the-world-of-autonomous-vehicles-84579.html" target=_blank>Coronavirus Crisis Changes the World of Autonomous Vehicles</a> 

在這裏插入圖片描述

  • 在源碼頁面直接點擊對應的a標籤的href屬性值,直接跳轉到對應的文章的頁面,

在這裏插入圖片描述
如下
在這裏插入圖片描述

  • 然後,再查看對應的源代碼,查找對應的文章在什麼位置

有兩處地方都有對應的文章,一方面< p > … < \p >標籤內如下圖

在這裏插入圖片描述

另外一方面,“[00:00.00]…”可以用正則表達式直接搜索,然後將獲取到的結果用“]”進行劃分,然後將後繼部分保存在文檔裏就行了,對應的正則表達式r’ [ [\d:.] *[ \ w ] * \ ] ’

在這裏插入圖片描述

  • 最後來看看翻頁的方式,"Report_"關鍵字進行連接
    在這裏插入圖片描述
程序編寫
  • 第一步確定大概的步驟

    • 獲取對應鏈接的html文本,基本的框架不變getHTMLText(url)
    • 對html文本進行解析,獲取標題,獲取連接parserHTML(text,ilt)
    • 對某一篇文章所在得具體的頁面進行瀏覽,保存文章storeText(path,url)
    • 將對應的文章標題的信息輸出到對應的控制檯printMessage(ilt)
    • 最後再用main()函數將所有的函數進行連接
  • 逐步完善各個步驟

import re
import requests
from bs4 import BeautifulSoup

def getHTMLText(url):
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ''


# 分解頁面
def parseHTMLText(text,ilt):
    soup = BeautifulSoup(text, 'html.parser')
    aTag = list(soup.find_all('a', target='_blank'))
    path = 'D:\SpiderTest'
    for a in range(len(aTag)):
        ilt.append(aTag[a].string)
        path1 = path + '\ ' + aTag[a].string + '.txt'
        url2 = 'https://www.51voa.com/' + aTag[a].attrs['href']
        storeText(path1, url2)


# 保存頁面
def storeText(path,url):
    text = getHTMLText(url)
    soup = BeautifulSoup(text,'html.parser')
    p = soup.find_all('p')
    # 這裏返回的不是對應的的string類型,是沒有辦法直接寫入的
    path = path.replace(' ','')
    path = path.replace('?','')
    with open(path,'w') as f:
        for i in range(len(p)):
            f.write(str(p[i].string))


# 將對應的信息輸出到控制檯
def printMessage(ilt):
    text = '{:<10}\t{:<20}'
    print(text.format("序號", "文章名"))
    count = 1
    for i in ilt:
        print(text.format(count, i))
        count += 1

# 用main函數將所有的程序連接起來
def main():
    url = 'https://www.51voa.com/Technology_Report_1.html'
    i = 4
    res = list()
    for i in range(2,4):
        text = getHTMLText(url)
        parseHTMLText(text,res)
        r = 'Report_'+str(i)
        target = re.findall(r'Report_\d',url)
        url = url.replace(target[0],r,1)
    printMessage(res)

main()

結果

在這裏插入圖片描述
在這裏插入圖片描述

注意點——就是我修改的bug
  • < tag > string < /tag >其中的string雖然真正調用的時候使用tag.string方法,但是不是string類型的,是NavigableString類型的,詳見下圖。而用IO流的時候,又只可以寫入string類型,所以這裏注意!

在這裏插入圖片描述

在這裏插入圖片描述

  • 調用BeautifulSoup時,記住要加上解析的格式,我就是老是忘記BeautifulSoup(text,‘html.parser’)

在這裏插入圖片描述

  • IO流中的文件的路徑是有特殊的要求的,不能有空格,不可以有問號,所以要講對應的特殊的不合法的字符完全清除
    在這裏插入圖片描述

在這裏插入圖片描述

  • 對於try——except的使用要注意,如果將文件讀寫放入其中,那麼對應的就不會報錯,但是隻會循環一次

在這裏插入圖片描述

  • 打開讀寫文件,比對文章之後發現,有很多的none,說明並沒有將所有的文章內容全部都爬取到對應的文檔內容中,有些內容變成了None。

在這裏插入圖片描述
通過分析發現,只要p標籤內部有別的非文本的內容,會自動讀取爲None

在這裏插入圖片描述
所以現在有以下幾種解決思路:

  • 對其進行寫入的時候進行一定的篩選和判定,如果所有的p標籤有對應的子孫類,那就對其單獨操作,沒有直接寫入
  • 採用正則表達式進行匹配,換一個地方進行匹配。
  • 採用第二種方式修改如下
# 保存頁面
def storeText(path,url):
    text = getHTMLText(url)
    regex = re.compile(r'[\[]{1}[\d\:\.]+[\]]{1}[a-zA-Z+\s+\.+\"\"\'\'\,+]+')
    reslist = regex.findall(text)
    # 這裏返回的不是對應的的string類型,是沒有辦法直接寫入的
    path = path.replace(' ','')
    path = path.replace('?','')
    count = 0
    with open(path,'a+') as f:
        for i in reslist:
            f.write(str(i.split(']')[1]))

結果如下,是一篇完整的文章!!!
在這裏插入圖片描述

  • 其實,還有一種用方法,你仔細看文章外面有個特殊的標籤,直接把標籤的內容寫入就行了

在這裏插入圖片描述

總結:
  • 最然很晚了,但是我還是很高興的,我終於寫出來了,終於寫出來了
  • 很有意思的一次實踐,我該繼續往下學習了,我還要學習數據分析,自己爬取數據,然後自動分析,豈不是很棒!!!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章