天天看點

從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接

前言

我們的目标

了解爬蟲

什麼是爬蟲

爬蟲的基本流程

能爬取那些資料

如何解析資料

python爬蟲架構

Python 爬蟲架構介紹

Scrapy介紹及架構圖

具體爬蟲操作

一、頁面擷取

二、目标提取

三、指定連結抓取

四、資料下載下傳&存儲

五、添加互動

附錄

Py2.x vs Py3.x

爬蟲腳本

從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接
馬蜂窩評論抄襲事件
從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接
經過資料分析,馬蜂窩上有7454個抄襲賬号,合計從攜程、藝龍、美團、Agoda、Yelp上抄襲搬運了572萬條餐飲點評與1221萬條酒店點評。有1800萬條是機器全網抓取的,各種評論截圖拼湊在一起 ,簡直觸目驚心!
從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接

了解爬蟲概念、流程、原理

首先肯定要實作圖檔抓取這個基本功能

然後實作對使用者所給的連結進行抓取

最後可以有一定的簡單互動

舉例來說:我們可以把網際網路比作一張大的蜘蛛網,資料便是存放于蜘蛛網的各個節點,而爬蟲就是一隻小蜘蛛,沿着網絡抓取自己的獵物(資料)。

從技術層面來說就是:通過程式模拟浏覽器請求站點的行為,把站點傳回的HTML代碼/JSON資料/二進制資料(圖檔、視訊) 爬到本地,進而提取自己需要的資料,存放起來使用。

模拟浏覽器發送請求(擷取網頁代碼)->提取有用的資料->存放于資料庫或檔案中

從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接

1、發起請求

使用http庫向目标站點發起請求,即發送一個Request

Request包含:請求頭、請求體等

Request子產品缺陷:不能執行JS 和CSS 代碼

2、擷取響應内容

如果伺服器能正常響應,則會得到一個Response

Response包含:html,json,圖檔,視訊等

3、解析内容

解析html資料:正規表達式(RE子產品),第三方解析庫如Beautifulsoup,pyquery等

解析json資料:json子產品

解析二進制資料:以wb的方式寫入檔案

4、儲存資料

文本:純文字,Json,Xml等

關系型資料庫:如mysql,oracle,sql server等結構化資料庫

非關系型資料庫:MongoDB,Redis等key-value形式存儲

網頁文本:如HTML文檔,Json格式化文本等

圖檔:擷取到的是二進制檔案,儲存為圖檔格式(妹子的圖檔...)

視訊:同樣是二進制檔案(想看的視訊...)

其他:隻要你能通過浏覽器通路的資料都可以通過爬蟲擷取(酒店資訊....)

直接處理

Json解析

正規表達式處理

BeautifulSoup解析處理

PyQuery解析處理

XPath解析處理

爬蟲架構主要由五個部分組成,分别是排程器、URL管理器、網頁下載下傳器、網頁解析器、應用程式(爬取的有價值資料)。

排程器:相當于一台電腦的CPU,主要負責排程URL管理器、下載下傳器、解析器之間的協調工作。

URL管理器:包括待爬取的URL位址和已爬取的URL位址,防止重複抓取URL和循環抓取URL,實作URL管理器主要用三種方式,通過記憶體、資料庫、緩存資料庫來實作。

網頁下載下傳器:通過傳入一個URL位址來下載下傳網頁,将網頁轉換成一個字元串,網頁下載下傳器有urllib2(Python官方基礎子產品)包括需要登入、代理、和cookie,requests(第三方包)

網頁解析器:将一個網頁字元串進行解析,可以按照我們的要求來提取出我們有用的資訊,也可以根據DOM樹的解析方式來解析。

常用的網頁解析器有:
           

正規表達式(直覺,将網頁轉成字元串通過模糊比對的方式來提取有價值的資訊,當文檔比較複雜的時候,該方法提取資料的時候就會非常的困難)

html.parser(Python自帶的)

beautifulsoup(第三方插件,html.parser 和 beautifulsoup 以及 lxml 都是以 DOM 樹的方式進行解析的)

lxml(第三方插件,可以解析 xml 和 HTML)

應用程式:就是從網頁中提取的有用資料組成的一個應用。

下面用一個圖來解釋一下排程器是如何協調工作的:

從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接

我們來看一下主流爬蟲架構在GitHub上的活躍度:

從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接

Scrapy是一個為了爬取網站資料,提取結構性資料而編寫的應用架構。 可以應用在包括資料挖掘,資訊處理或存儲曆史資料等一系列的程式中。Scrapy 使用 Twisted這個異步網絡庫來處理網絡通訊,架構清晰,并且包含了各種中間件接口,可以靈活的完成各種需求。

我們以百度貼吧為例,一步步教你如何進行圖檔爬取。

尋找規律,分析規律

圖中的黑色方框左邊填寫xpth,右邊會傳回對應的結果,可以看到目前頁面的文章全部抓取到了。xpth具體怎麼寫要根據右邊的檢查元素來具體分析,每個網站的方式不一樣,但是細心尋找可以找到相同的規律。

從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接

找到規律并能比對上開始寫代碼了:go

要讓python可以進行對網頁的通路,那肯定要用到urllib.request包

urllib中有 urlopen(str) 方法用于打開網頁并傳回一個對象,調用這個對象的read()方法後能直接獲得網頁的源代碼,内容與浏覽器右鍵檢視源碼的内容一樣。

從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接

分析目前頁面所有的貼吧名,即:/p/xxxxxxx

之後拼接 “host + 貼吧名”,行程最終的貼吧連結

從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接

進入每個文章後,再對文章内的圖檔進行一次過濾,僅比對與樓主上傳的相關圖檔

從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接

爬取貼吧前多少頁的資料

從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接
從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接
從馬蜂窩事件了解網絡爬蟲-- coding:utf-8 --取出每個文章裡的每個圖檔連接配接

Py2.x:Urllib庫、Urllin2庫

Py3.x:Urllib庫

變化:

2.x vs 3.x

在Pytho2.x中使用import urllib2——-對應的,在Python3.x中會使用import urllib.request,urllib.error。

在Pytho2.x中使用import urllib——-對應的,在Python3.x中會使用import urllib.request,urllib.error,urllib.parse。

在Pytho2.x中使用import urlparse——-對應的,在Python3.x中會使用import urllib.parse。

在Pytho2.x中使用import urlopen——-對應的,在Python3.x中會使用import urllib.request.urlopen。

在Pytho2.x中使用import urlencode——-對應的,在Python3.x中會使用import urllib.parse.urlencode。

在Pytho2.x中使用import urllib.quote——-對應的,在Python3.x中會使用import urllib.request.quote。

在Pytho2.x中使用cookielib.CookieJar——-對應的,在Python3.x中會使用http.CookieJar。

在Pytho2.x中使用urllib2.Request——-對應的,在Python3.x中會使用urllib.request.Request。

爬取百度貼吧貼主的圖檔

-- coding:utf-8 --

import urllib.request

from lxml import etree

def loadPage(url):

"""

作用:根據url發送請求,擷取伺服器響應檔案
url: 需要爬取的url位址           

"""

# headers = {"User-Agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"}

request = urllib.request.Request(url)

html = urllib.request.urlopen(request).read()

# 解析HTML文檔為HTML DOM模型

content = etree.HTML(html)

# print content

# 傳回所有比對成功的清單集合

link_list = content.xpath('//div[@class="t_con cleafix"]/div/div/div/a/@href')

# link_list = content.xpath('//a[@class="j_th_tit"]/@href')

for link in link_list:

fulllink = "http://tieba.baidu.com" + link
  # 組合為每個文章的連結
  # print link
  loadImage(fulllink)
           

取出每個文章裡的每個圖檔連接配接

def loadImage(link):

headers = {

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}           

request = urllib.request.Request(link, headers=headers)

# 解析

# 取出文章裡每層層主發送的圖檔連接配接集合

# link_list = content.xpath('//img[@class="BDE_Image"]/@src')

# link_list = content.xpath('//div[@class="post_bubble_middle"]')

link_list = content.xpath('//img[@class="BDE_Image"]/@src')

# 取出每個圖檔的連接配接

print("link:" + link)
  writeImage(link)
           

def writeImage(link):

作用:将html内容寫入到本地
link:圖檔連接配接           

# print "正在儲存 " + filename

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}           

# 檔案寫入

request = urllib.request.Request(link, headers=headers)

# 圖檔原始資料

image = urllib.request.urlopen(request).read()

# 取出連接配接後10位做為檔案名

filename = link[-10:]

# 寫入到本地磁盤檔案内

with open("/Users/didi/Downloads/crawlertest/" + filename, "wb") as f:

f.write(image)           

# print("已經成功下載下傳 " + filename)

def tiebaSpider(url, beginPage, endPage):

作用:貼吧爬蟲排程器,負責組合處理每個頁面的url
url : 貼吧url的前部分
beginPage : 起始頁
endPage : 結束頁           

for page in range(beginPage, endPage + 1):

pn = (page - 1) * 50
  filename = "第" + str(page) + "頁.html"
  print(filename)
  fullurl = url + "&pn=" + str(pn)
  print(fullurl)
  loadPage(fullurl)
  # print html
   
  print("下載下傳完成")
           

if name == "__main__":

kw = input("請輸入需要爬取的貼吧名:")

beginPage = int(input("請輸入起始頁:"))

endPage = int(input("請輸入結束頁:"))

url = "http://tieba.baidu.com/f?"

key = urllib.parse.urlencode({"kw": kw})

fullurl = url + key

tiebaSpider(fullurl, beginPage, endPage)

繼續閱讀