search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

一個Python小白的5個小時爬蟲經歷

復旦大數據

ID:FuDanBigData

前言

最近業餘在做一個基於.NETCore的搜索項目,奈何基層代碼寫好了,沒有看起來很華麗的數據供測試。很巧的也是博客搜索,於是乎想到了博客園。C# 也能做做頁面數據抓取的,不過在博客園看到的大部分都是python實現,所以就臨時想了一下看看python到底是什麼東東。

不看基礎語法,不看語言功能,直接上代碼,哪裡不會搜哪裡。代碼完成總共用時大概4個小時,其中搭建環境加安裝BeautifulSoup大概1個小時。解析HTML用時間最多了,邊看demo邊解析,大概2個小時,剩下的時間就是調試加保存數據了。

環境搭建

既然用python,那麼自然少不了語言環境。於是乎到官網下載了3.5版本的。安裝完之後,隨機選擇了一個編輯器叫PyCharm,話說python編輯器還真挺多的。由於本人是小白,所以安裝事項不在過多贅述。

建好項目,打開編輯器,直接開工。本來之前用C#寫的時候,大體思路就是獲取網頁內容,然後正則匹配。後來發現網上的帖子也很多。不過在搜索過程中發現,不建議用正則來匹配HTML。有正好我的正則不太好,所以我就搜了一下HTML解析工具,果不其然,人家都做好了,直接拿來用吧。沒錯就是這個東東:BeautifulSoup。

安裝也很簡單,不過中間出了個小插曲,就是bs4沒有。繼續搜,然後需要用pip安裝一下就好了。(當然我並不知道bs4和pip是什麼鬼)

思路分析

博客嗎,我當然就對準了博客園,於是乎,進入博客園首頁,查看請求。

發送請求

當然我不知道python是怎麼進行網路請求的,其中還有什麼2.0和3.0的不同,中間曲曲折折了不少,最終還是寫出了最簡單的一段請求代碼。

  • importurllib.parse

  • importurllib.request

  • # params CategoryId=808 CategoryType=SiteHome ItemListActionName=PostList PageIndex=3 ParentCategoryId=0 TotalPostCount=4000

  • defgetHtml(url,values):

  • user_agent='Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36'

  • headers = {'User-Agent':user_agent}

  • data = urllib.parse.urlencode(values)

  • response_result = urllib.request.urlopen(url+'?'+data).read

  • html = response_result.decode('utf-8')

  • returnhtml

  • #獲取數據

  • defrequestCnblogs(index):

  • print('請求數據')

  • url ='http://www.cnblogs.com/mvc/AggSite/PostList.aspx'

  • value= {

  • 'CategoryId':808

  • 'CategoryType':'SiteHome'

  • 'ItemListActionName':'PostList'

  • 'PageIndex': index,

  • 'ParentCategoryId':0

  • 'TotalPostCount':4000

  • }

  • result = getHtml(url,value)

  • returnresult

其實博客園這個請求還是挺標準的,哈哈正好適合抓取。因為他返回的就是一段html。(如果返回json那不是更好。。。。)

數據解析

上文已經提到了,用到的是BeautifulSoup,好處就是不用自己寫正則,只要根據他的語法來寫就好了,在多次的測試之後終於完成了數據的解析。

先上一段HTML。然後在對應下面的代碼,也許看起來更輕鬆一些。

  • <divclass="post_item"

  • <divclass="digg"

  • <divclass="diggit"onclick="DiggPost('hyper-xl'64177412812381)"

  • <spanclass="diggnum"id="digg_count_6417741"1</span>

  • </div>

  • <divclass="clear"></div>

  • <divid="digg_tip_6417741"class="digg_tip"></div>

  • </div>

  • <divclass="post_item_body"

  • <h3><aclass="titlelnk"href="http://www.cnblogs.com/hyper-xl/p/6417741.html"target="_blank"Python 字元串格式化</a></h3>

  • <pclass="post_item_summary"

  • <ahref="http://www.cnblogs.com/hyper-xl/"target="_blank"

  • <imgwidth="48"height="48"class="pfs"

  • src="//pic.cnblogs.com/face/795666/20160421231717.png"alt=""/>

  • </a> 轉載請註明出處 Python2.6+ 增加了str.format函數,用來代替原有的'%'操作符

  • 。它使用比'%'更加直觀、靈活。下面詳細介紹一下它的使用方法。 下面是使用'%'的例子: 格式很像C語言的printf是不是?由於'%'是一個操作符,只能在左右

  • 兩邊各放一個參數,因此右邊多個值需要用元組或 ...

  • </p>

  • <divclass="post_item_foot"

  • <ahref=class="lightblue"新月的力量_141</a>

  • 發佈於 2017-02-19 23:07

  • <spanclass="article_comment"

  • <ahref="http://www.cnblogs.com/hyper-xl/p/6417741.html#commentform"title=""class="gray"

  • 評論(0)

  • </a>

  • </span>

  • <spanclass="article_view"

  • <ahref=class="gray"

  • 閱讀

  • (138)

  • </a>

  • </span>

  • </div>

  • </div>

  • <divclass="clear"></div>

  • </div>

通過上文的HTML代碼可以看到幾點。首先每一條數據都在 div(class="post_item")下。然後 div("post_item_body")下有用戶信息,標題,鏈接,簡介等信息。逐一根據樣式解析即可。

代碼如下:

  • frombs4importBeautifulSoup

  • importrequest

  • importre

  • #解析最外層

  • defblogParser(index):

  • cnblogs = request.requestCnblogs(index)

  • soup =BeautifulSoup(cnblogs,'html.parser')

  • all_div = soup.find_all('div', attrs={'class':'post_item_body'}, limit=20)

  • blogs =

  • #循環div獲取詳細信息

  • foriteminall_div:

  • blog = analyzeBlog(item)

  • blogs.append(blog)

  • returnblogs

  • #解析每一條數據

  • defanalyzeBlog(item):

  • result = {}

  • a_title = find_all(item,'a''titlelnk')

  • ifa_titleisnotNone:

  • # 博客標題

  • result["title"] = a_title[0].string

  • # 博客鏈接

  • result["href"] = a_title[0]['href']

  • p_summary = find_all(item,'p''post_item_summary')

  • ifp_summaryisnotNone:

  • # 簡介

  • result["summary"] = p_summary[0].text

  • footers = find_all(item,'div''post_item_foot')

  • footer = footers[0]

  • # 作者

  • result["author"] = footer.a.string

  • # 作者url

  • result["author_url"] = footer.a['href']

  • str = footer.text

  • time = re.findall(r"發佈於 .+? .+? ", str)

  • result["create_time"] = time[0].replace('發佈於 ''')

  • comment_str = find_all(footer,'span''article_comment')[0].a.string

  • result["comment_num"] = re.search(r'\d+', comment_str).group

  • view_str = find_all(footer,'span''article_view')[0].a.string

  • result["view_num"] = re.search(r'\d+', view_str).group

  • returnresult

  • deffind_all(item,attr,c):

  • returnitem.find_all(attr,attrs={'class':c},limit=1)

上邊一堆代碼下來,著實花費了我不少時間,邊寫邊調試,邊百度~~不過還好最終還是出來了。等數據都整理好之後,然後我把它保存到了txt文件裡面,以供其他語言來處理。本來想寫個put直接put到ElasticSearch中,奈何沒成功。後邊在試吧,畢竟我的重點只是導數據,不在抓取這裡。

  • importmatch

  • importos

  • importdatetime

  • importjson

  • defwriteToTxt(list_name,file_path):

  • try:

  • #這裡直接write item 即可,不要自己給序列化在寫入,會導致json格式不正確的問題

  • fp = open(file_path,"w+",encoding='utf-8')

  • l = len(list_name)

  • i =0

  • fp.write('[')

  • foriteminlist_name:

  • fp.write(item)

  • ifi<l-1:

  • fp.write(',\n')

  • i +=1

  • fp.write(']')

  • fp.close

  • exceptIOError:

  • print("fail to open file")

  • #def getStr(item):

  • # return json.dumps(item).replace('\'','\"')+',\n'

  • defsaveBlogs:

  • foriinrange(12):

  • print('request for '+str(i)+'...')

  • blogs = match.blogParser(i,5)

  • #保存到文件

  • path = createFile

  • writeToTxt(blogs,path+'/blog_'+ str(i) +'.json')

  • print('第'+ str(i) +'頁已經完成')

  • return'success'

  • defcreateFile:

  • date = datetime.datetime.now.strftime('%Y-%m-%d')

  • path ='/'+date

  • ifos.path.exists(path):

  • returnpath

  • else:

  • os.mkdir(path)

  • returnpath

  • result = saveBlogs

  • print(result)

上邊呢,我取了一百頁的數據,也就是大概2000條做測試。

成果驗收

廢了好大勁終於寫完那些代碼之後呢,就可以享受勝利的果實了,雖然是初學者,代碼寫的很渣,這參考一下,那參考一下,不過還是有些收穫的。運行效果如下:

生成的文件:

文件內容:

總結

一個簡單的抓取程序就寫完了,python還真是TM的好用。以後有空再研究研究吧。代碼行數算上空行和註釋總共100 (50+25+25)行。湊個整數好看點~~現在認識字我感覺就可以上手寫程序了。這裡百度一下,那裡google一下,問題就解決了,程序也出來了,大功告成。

是時候該和python暫時告別了,繼續我的。NET事業。話說上次做rss採集的時候,好多".NET要完蛋了","為什麼我們不招.NET" 是什麼鬼。

1:一百多篇大數據文檔下載!

2超全數據分析資料免費下載!(包括SQL,R語言,SPSS,SAS,python,數據分析和數據挖掘)

3清華大學數據科學院講座內容集錦免費下載!

4Python超全資料分享!



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦