好久沒有更博客了!因爲疫情在家閒置了半年,思維都不怎麼活躍了,而且剛上班這會,突然對技術失去了激情。沒有什麼動力去鞭策自己去學習,有一種要混喫等死得感覺。
在意識到這樣不行之後,我覺得要給自己佈置點作業了。四月底上了一週班,就是愉快得五一,五一過後正式上班忙工作。去年年底到五月,積累了一堆得活,又是維護線上得項目改改bug,又是新增接口,再加之懶散隨意得習氣,拖到5.20號才活過來。在大家陪女朋友的時候,寂寞無奈之下,開始找點刺激的新意。
具體是啥呢,上圖看看:
之前學過python,有點語法基礎,因爲它跟scala語言比較像,用起來也不是很順手。所以就用python寫了一個簡單的爬蟲,沒有用scrapy框架那些,只是單純的引用了一下requests和bs4或者selenium。上面的這些都是合法網站上的資源,並不大家想象那種哈。不過這些圖片拿來做一些設計、繪畫創造還是挺好的,沒事看看也挺賞心悅目的。
一、環境工具:
python3.6
pycharm2018.1
1、模擬瀏覽器請求獲取的html頁面內容;
2、通過第三方類庫解析html,拿到頁面的資源
3、保持資源到數據庫或者本地
三、創建一個py文件,寫代碼(爲了各位身體着想,下面用爬取小說做案例吧)
目標網站:建議選一些小站,沒有VIP那種。可以免去大站的登陸驗證,反爬蟲機制
第一步分析網站內容構成:先從入口網頁開始。用谷歌瀏覽器,F12查看頁面元素
這是一個小說的目錄頁,通過查看元素可以看到,該頁面包含它每個章節的鏈接和標題。
通過章節的url可以看出,就是目錄頁中的href屬性拼上域名。
思路:我們要先拿到這個頁面的所有鏈接和標題,組成一組二元tuple,放到一個list集合中。然後便利這個集合,從每個tuple中取到url去爬取單章節的文本內容,寫到TXT文本中,並且以這個標題命名即可。最終會在某個目錄下生成所有分章節的txt文本。
而在爬取章節頁面的時候,又發現了,內容文本是通過js函數動態添加的。如果直接通過上面拼接的url取訪問,爬取的html裏是沒有內容的。這裏取巧就用了selenium 這個框架,它能直接操作瀏覽器的內核,完完全全模擬的人瀏覽網頁的行爲。
from selenium import webdriver
import time
import logging #日誌模塊
logger=logging.getLogger("__name__")
#驅動版本要跟谷歌瀏覽器版本對應,沒有對應的選擇相近版本的也行
driver_dir="D:\pyproject\PythonLearn\driver\chromedriver.exe"
#加載瀏覽器的驅動
driver = webdriver.Chrome(driver_dir)
#目錄頁url
index_url = 'https://www.biqukan.com/1_1496/'
#用作拼接章節頁時,補充的前置域名
base_url = 'https://www.biqukan.com/'
#獲取目錄頁的 a標籤: 帶了href的url和txt章節名
def get_urls(url):
#讓瀏覽器訪問目錄頁
html= driver.get(url)
#爬取目錄頁的所有A標籤
links=driver.find_elements_by_css_selector('.listmain dd a')
return links
def get_txtcontent(url):
#讓頁面刷新到章節頁
html= driver.get(url)
#獲取章節的標題做文件名
link=driver.find_elements_by_css_selector('.content h1')
title=link[0].get_attribute("textContent")
#獲取章節的內容文本
txts=driver.find_elements_by_css_selector('.showtxt')
word=txts[0].get_attribute("textContent")
#保存文件
with open("D:\\pyData\\xiaoshuo\\%s.txt" % title, "w", encoding="utf-8") as f:
word.replace('\xa0'*8,u'')
f.write(word) # 寫入
f.write('\n')
if __name__ == '__main__':
try:
allurl= get_urls(index_url)
#拿到目錄頁的href放到list集合中
arr=list()
for link in allurl:
url=link.get_attribute("href")
arr.append(url)
#便利集合,去爬取每個章節頁,並保存到本地文本TXT
for u in arr:
get_txtcontent(u)
#休息3S,防止頁面沒刷新完全,或者訪問頻繁被網站攔截IP
time.sleep(3)
except:
logger.error("========")
這裏面的代碼和步驟都寫了註釋,下面就不細說了。
運行代碼,然後去本地目錄查看小說章節情況:
爬取圖片,思路是類似的。不過寫文件的時候是二進制文件,得用下面“wb”或“wb+”形式
with open(fileDir+"\\"+name,"wb+") as file:
file.write(jpg.content)
總結:這是一種簡單得單線程爬蟲形式。爬取少量資源得時候可以用用,爬取大量資源得時候,像圖片音頻這些。最好使用框架多線程異步進行,提升效率。我目前正在用scrapy框架寫一些案例,還沒做整理,後面有機會再做交流。