Python – Crawler -找尋網頁中指定資料並排序

內容目錄

簡介

python爬蟲其實目前用下來最好用的工具就是『bs4+request』,但是會遇到每個平台的新聞文章或是論壇文章等內容,html的格式都長的不同,用bs4要客製化每一個網頁去抓取可能會花很多很多時間,所以我就選用了Newspaper套件,但是該套件會把抓的內容分類成一個list,例如內文、圖片、標題,所以在要重置的時候會遇到文字跟圖片分開,讓我們不知道正確的圖文排佈狀況。

所以這篇就使用土法煉鋼法,透過Newspaper找到的文字、圖片字串,去解析透過從bs4抓下來的html來找尋圖文順序,並重新產出一個新的圖文list。

實作

Step1:將透過Newspaper抓下來的內文文字與圖片塞到同一個list中。

content_word_list = []
        for sub_tag in content.splitlines():
            if len(sub_tag)>3:
                content_word_list.append(sub_tag)

        for image_tag in All_images:
            content_word_list.append(image_tag)

這邊要解釋一下,首先我們先創建一個空list來塞文字跟圖片連結。看到第一個for-loop,要注意的是,從Newspaper抓下來的內文他每一筆資料之間都會有一個空格儲存格,所以我們要透過『splitline()』將空格移除,這樣才可以準確地將每一串文字塞到一格之中。

第二個for-loop是幫剛剛處理完儲存文字部分再接續的將圖片連結塞進list中。

Step2:取得該文章body中的html格式內容。

web_url = "文章網址"

response = requests.get(web_url)
response.encoding='utf8'
soup = BeautifulSoup(response.text, "html.parser")
soup = soup.select('body')
print(soup)

透過『bs4+request』老方法把整篇網頁的html抓下來,之後要給比對陣列使用,這邊我們可以將抓下來的html精簡一點,決大部分的文章資料都是塞在『<body>』之中,所以我們可以將一大串的html程式碼精簡,只留著『<body></body>』裡的內容。

Step3:將html-body的每一列都塞到被比對陣列中。

count = 0  #比較出的內容索引
result_list = [] #比較出塞入完整的排序陣列
compare_list = [] #比較過後暫存的陣列
index_list = [] #索引值陣列
index_max = 0 #給索引直陣列容器最大化

 for word in str(soup).split('\n'):
    compare_list.append(word)
    count += 1

將提取出的html-body一列一列拆開,儲存到『被比較陣列中』,這邊要注意的是,需要將soup取出的內容強制轉換成字串型態,並處理斷行的動作,並計算整個陣列有幾個單位,其實也可以塞完透過『len(list)』來取得陣列大小。

Step4:比較內文出現字串與html的list位置。

  for i in word_list:
    for j in compare_list:
      if i in j:
        index_list.append(compare_list.index(j))

這階段的處理功能是把1.newspaper儲存的內容陣列跟2.bs4儲存的陣列做比對後,將資料相符合的陣列索引值儲存到索引值陣列,這概念有點像字典前幾頁有單字類別分類的頁數功能相同。

Step5:將result_list擴增。

for y in index_list:
    if y > index_max:
      index_max = y

  for i in range(index_max):
      result_list.append('')

由於我們已經比對完成後,知道每一筆資料的索引直在2.bs4儲存的陣列,所以我們把最終產出的『result_list』做一個擴增的動作,在第一個for-loop是判斷我們的result_list陣列容器空間,第二個for-loop是把所有索引直都塞入空字串。

Step6:把便是好的資料依序塞入指定位置。

for i in word_list:
    for j in compare_list:
      if i in j:
        result_list.insert(compare_list.index(j),i)

當我們擴充好result_list之後,透過雙重for-loop將索引過後的資料塞到指定陣列中,這邊我用到list的一個功能叫做『insert』,使用方式是『insert(要塞的位置 , 塞的內容)』。

Step7:刪除空字串的陣列。

  while '' in result_list:
    result_list.remove('')
    
  print(result_list)

到最後一步了,我們剛剛再擴充result_list時,都有把每一個空間都塞一個空字串,再來在上一步驟是指定位置把『””』換成我們排序好的圖文內容,所以result_list陣列中有非常多的空字串,這邊我們就要把他移除,使用了『remove()』,最後就完成已經做好比對且排序好的list了。

小結

這次算是一個在使用多重工具下,為了達到我們想要的成果所客製化的一個小處理工具,雖然說使用到非常非常暴力的方法,但是起碼有達到我們想要的。可以看到上圖一個是比對排序前,一個是比對排序後,在排序完之後進而塞入sheet中,就可以使用自動化程式來填入文章中並發布。在之後也可以找找有沒有更聰明的方法。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *