1:先說一下什么是網(wǎng)絡(luò)爬蟲
爬蟲顧名思義,(網(wǎng)絡(luò)機(jī)器人弧蝇,網(wǎng)頁蜘蛛),是一總按照一定規(guī)則的進(jìn)行自動爬取數(shù)據(jù)迄汛。
那么數(shù)據(jù)有事從何而來呢?
像百度捍壤、騰訊和阿里巴巴這樣的BAT企業(yè),本身就積累了大量的數(shù)據(jù)鞍爱,所以他們玩起大數(shù)據(jù)來鹃觉,多半是“悶聲發(fā)大財”。
吾等屌絲沒有數(shù)據(jù)睹逃,如何玩呢?
首先盗扇,你可以通過第三方購買數(shù)據(jù),比如說沉填,數(shù)據(jù)堂就有很多數(shù)據(jù)出售和分享;其次疗隶,你可以用爬蟲爬回一些數(shù)據(jù)來存儲;
那么我們就又說回來數(shù)據(jù)爬蟲了,我們先說一下都有什么辦法來爬取數(shù)據(jù)翼闹。
2:用request這個模塊來進(jìn)行爬蟲:
下面是代碼:
#先導(dǎo)入我們需要的模塊
import urllib.request
# 在客戶端發(fā)出每個請求時斑鼻,服務(wù)器都會創(chuàng)建一個request對象,并把請求數(shù)據(jù)封裝到request中猎荠,然后我們找個變量來接收
request = urllib.request.Request("http://www.china8823.top")
# Request對象作為urlopen()方法的參數(shù)坚弱,發(fā)送給服務(wù)器并接收響應(yīng)
#urlopen,函數(shù)用于實現(xiàn)對目標(biāo)url的訪問
response = urllib.request.urlopen(request)
#將獲取到的頁面源碼关摇,轉(zhuǎn)為字符串
html = response.read().decode('utf-8')
print (html)
那么就會有人問了有沒有簡單有速度快一點的方法呢荒叶!當(dāng)然有了!請看下面输虱。
3:在說一個簡單又速度快的方法些楣。
那就是XPath,我們可以先將 HTML文件 轉(zhuǎn)換成 XML文檔宪睹,然后用 XPath 查找 HTML 節(jié)點或元素愁茁。
什么是XPath? xpath (XML Path Language) 是一門在 XML 文檔中查找信息的語言横堡,可用來在 XML 文檔中對元素和屬性進(jìn)行遍歷埋市。
那什么又是XML呢? XML可以理解為就是一個HTML文本語言(他可不是HTML語言只是類似)命贴,把我們需要爬取的數(shù)據(jù)網(wǎng)頁轉(zhuǎn)換成XML文本語言然后我們在去用XPath進(jìn)行數(shù)據(jù)提取道宅。
XPath:他呢表達(dá)式很簡單
表達(dá)式 | 描述 |
---|---|
nodename | 選取此節(jié)點的所有子節(jié)點食听。 |
/ | 從根節(jié)點選取。 |
// | 從匹配選擇的當(dāng)前節(jié)點選擇文檔中的節(jié)點污茵,而不考慮它們的位置樱报。 |
. | 選取當(dāng)前節(jié)點。 |
.. | 選取當(dāng)前節(jié)點的父節(jié)點泞当。 |
@ | 選擇屬性迹蛤。 |
下面是實例
#導(dǎo)入所需要的包
import os
import urllib
import urllib2
from lxml import etree
def qidianSpider(start_url):
get_noval_list_by_url(start_url)
def get_noval_list_by_url(req_url):
"""
#根據(jù)分頁的url,獲取分頁的頁面源碼,提取小說的信息
#req_url:表示每一個分頁的url
"""
#構(gòu)建一個請求頭
req_header = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}
#發(fā)起請求襟士,獲取響應(yīng)結(jié)果
response = requests.get(url=req_url,headers=req_header)
if response.status_code == 200:
#提取小說的信息
#使用etree.HTML可以將html文檔源碼,轉(zhuǎn)為一個element對象,
#然后才能使用xpath語法
html_element = etree.HTML(response.text)
# div = html_element.xpath('/html/body/div[1]')
#div = html_element.xpath('/html/body/div[@class="share-img"]')
#src = html_element.xpath('//div[@class="share-img"]/img/@src')[0]
#提取小說列表
noval_lis = html_element.xpath('//ul[@class="all-img-list cf"]/li')
print(len(noval_lis))
print(noval_lis)
for noval_li in noval_lis:
#封面圖片
coverImage = noval_li.xpath('./div[@class="book-img-box"]/a/img/@src')[0]
# coverImage = noval_li.xpath('./div[@class="book-img-box"]//img/@src')[0]
#標(biāo)題
title = noval_li.xpath('./div[@class="book-mid-info"]/h4/a/text()')[0]
#作者
author = noval_li.xpath('.//a[@class="name"]/text()')[0]
print(coverImage, title, author)
if __name__ == '__main__':
start_url = 'https://www.qidian.com/all?orderId=&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=0&page=1'
qidianSpider(start_url)
4:下面在說一下多線程爬蟲吧盗飒,在什么情況下要用多線程,為什么要用多線程陋桂。
原因很簡單:
因為我們之前寫的爬蟲都是單個線程的逆趣?這怎么夠?一旦一個地方卡到不動了嗜历,那不就永遠(yuǎn)等待下去了宣渗?為此我們可以使用多線程或者多進(jìn)程來處理。
一個簡單的線程:
import threading
from time import sleep
def lyh(num,classname):
print(num,classname)
for i in range(5):
print('對不起' + str(i),threading.currentThread().name)
if __name__ == '__main__':
print('主線程開啟'+threading.currentThread().name)
for i in range(5):
threed1 = threading.Thread(target=lyh,name='xiancheng',args=(10,1805))
#主線程結(jié)束后不會檢查字線程是否完那程
#一旦誅仙程結(jié)束梨州,字線程同時頁結(jié)束
threed1.daemon=True
threed1.start()
print('主線程結(jié)束'+threading.currentThread().name)
#線程之間的執(zhí)行是沒有先后的痕囱,不知道會縣執(zhí)行哪一個