Python爬蟲基礎知識講解


Python爬蟲主要是爲了方便學習新語言和學習資料的爬取

1 瞭解robots.txt

1.1 基礎理解

robots.txt是一個純文本文件,在這個文件中網站管理者能夠聲明該網站中不想被robots訪問的部分,或者指定搜索引擎只收錄指定的內容,通常域名後加/robots.txt,就能夠獲取
當一個搜索機器人(有的叫搜索蜘蛛)訪問一個站點時,它會首先檢查該站點根目錄下是否存在robots.txt,若是存在,搜索機器人就會按照該文件中的內容來肯定訪問的範圍;若是該文件不存在,那麼搜索機器人就沿着連接抓取
另外,robots.txt必須放置在一個站點的根目錄下,並且文件名必須所有小寫。
robots.txt寫做語法
首先,咱們來看一個robots.txt範例:https://fanyi.youdao.com/robots.txt
訪問以上具體地址,咱們能夠看到robots.txt的具體內容以下html

User-agent: Mediapartners-Google
Disallow:

User-agent: *
Allow: /fufei
Allow: /rengong
Allow: /web2/index.html
Allow: /about.html
Allow: /fanyiapi
Allow: /openapi
Disallow: /app
Disallow: /?

以上文本表達的意思是容許全部的搜索機器人訪問fanyi.youdao.com站點下的全部文件
具體語法分析:User-agent:後面爲搜索機器人的名稱,後面若是是*,則泛指全部的搜索機器人;Disallow:後面爲不容許訪問的文件目錄python

1.2 使用robots.txt

robots.txt自身是一個文本文件。它必須位於域名的根目錄中並被命名爲robots.txt。位於子目錄中的 robots.txt 文件無效,由於漫遊器只在域名的根目錄中查找此文件。例如,http://www.example.com/robots.txt 是有效位置,http://www.example.com/mysite/robots.txt 則不是有效位置web

2 Cookie

因爲http/https協議特性是無狀態特性,所以須要服務器在客戶端寫入cookie,可讓服務器知道此請求是在什麼樣的狀態下發生api

2.1 兩種cookie處理方式

cookie簡言之就是讓服務器記錄客戶端的相關狀態信息,有兩種方式:服務器

  • 手動處理
    經過抓包工具獲取cookie值,而後將該值封裝到headers中
headers={
        'cookie':"...."
    }
在發起請求時把cookie封裝進去
  • 自動處理
    自動處理時,要明白cookie的值來自服務器端,在模擬登錄post後,服務器端建立並返回給客戶端
    主要是經過session會話對象來操做cookiesession做用:能夠進行請求的發送;若是請求過程當中產生了cookie會自動被存儲或攜帶在該session對象中
    建立session對象:session=requests.Session(),使用session對象進行模擬登錄post請求發送(cookie會被存儲在session中)
    發送session請求:session.post()在發送時session對象對要請求的頁面對應get請求進行發送(攜帶了cookie

3 經常使用爬蟲方法

python爬取數據解析原理:cookie

  • 標籤訂位
  • 提取標籤、標籤屬性中存儲的數據值

3.1 bs4

3.1.1 基礎介紹

bs4進行網頁數據解析
bs4解析原理:session

  • 經過實例化一個BeautifulSoup對象,而且將頁面源碼數據加載到該對象中
  • 經過調用BeautifulSoup對象中相關的屬性或者方法進行標籤訂位和數據提取

環境安裝:app

pip install bs4
pip install lxml

3.1.2 bs4使用

3.1.2.1 獲取解析對象

如何實例化BeautifulSoup對象:
導包from bs4 import BeautifulSoup
對象的實例化,有兩種,本地和遠程:工具

  1. 將本地的html文檔中的數據加載到該對象中
fp = open('./test.html','r',encoding='utf-8')
soup=BeautifulSoup(fp,'lxml') #指定lxml解析方式
  1. 將互聯網上獲取的頁面源碼加載到該對象中
page_text = response.text
soup=BeautifulSoup(page_text,'lxml')

3.1.2.2 使用bs4解析

使用bs4提供的用於數據解析的方法和屬性:post

  • soup.tagName:返回的是文檔中第一次出現的tagName對應的標籤,好比soup.a獲取第一次出現的a標籤信息

  • soup.find()
    在使用find('tagName')效果是等同於soup.tagName
    進行屬性定位,soup.find(‘div’,class_(或id或attr)='song'):示例就是定位帶有class='song'div標籤,class_必須有下劃線是爲了規避python關鍵字
    還能夠是其餘好比:soup.find(‘div’,id='song'):定位id是song的div標籤
    soup.find(‘div’,attr='song'):定位attr是song的div標籤

  • soup.find_all('tagName'):返回符合要求的全部標籤(列表)

select用法:

獲取標籤之間文本數據
可使用textstringget_text(),主要區別:

  • textget_text()能夠獲取某一個標籤中全部的文本內容
  • string:只能夠獲取該標籤下面直系的文本內容

獲取標籤中屬性值:

  • 使用python獲取字典方法獲取,好比:soup.a['href']就是獲取<a>中的href

3.1.2 使用例子

import os
import requests
from bs4 import BeautifulSoup


headers={
        'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
    }
url="https://www.test.com/chaxun/zuozhe/77.html"


def getPoems():
    res= requests.get(url=url,headers=headers)
    res.encoding='UTF-8'
    page_text=res.text
    #在首頁解析出章節
    soup = BeautifulSoup(page_text,'lxml')
    shici_list = soup.select(".shici_list_main > h3 > a")
    shici_name=[]
    for li in shici_list:
        data_url = "https://www.test.com"+li['href']
        # print(li.string+"======="+data_url)
        shici_name.append(li.string)
        detail_res = requests.get(url=data_url,headers=headers)
        detail_res.encoding='UTF-8'
        detail_page_text=detail_res.text
        detail_soup = BeautifulSoup(detail_page_text,'lxml')
        detail_content = detail_soup.find("div",class_="item_content").text
        # print(detail_content)
        with open("./shici.txt",'a+',encoding= 'utf8') as file:
            if shici_name.count(li.string)==1:
                file.write(li.string)
            file.write(detail_content+"\n")
            print(li.string+"下載完成!!!!")     
        

if __name__=="__main__":
    getPoems()

3.2 xpath

xpath解析:最經常使用且最便捷高效的一種解析方式

3.2.1 xpath基礎介紹

xpath解析原理:

  • 實例化一個etree的對象,且須要將被解析的頁面源碼數據加載到該對象中
  • 調用etree對象中的xpath方法結合着xpath表達式實現標籤的定位和內容的捕獲

環境安裝:

pip install lxml

3.2.2 xpath使用

3.2.2.1 獲取相關對象

先實例化一個etree對象,先導包:from lxml import etree

  1. 將本地的html文檔中的源碼數據加載到etree對象中
tree=etree.parse(filepath)
  1. 能夠將從互聯網上獲取的源碼數據加載到該對象中
page_text = response.text
tree=etree.HTML(page_text)

3.2.2.2 經過xpath解析

經過xpath表達式:tree.xpath(xpath表達式)
xpath表達式:

  • /:表示的是從根節點開始定位,表示的是一個層級
  • //:表示的是多個層級,能夠表示從任意位置開始定位
  • 屬性定位:tag[@attrName='attrValue']
    好比//div[@class='song']表示的是獲取到任意位置class='song'<div>標籤
  • 索引定位://div[@class='song']/p[3]表示的是任意位置class='song'<div>標籤下面的第三個<p>標籤,注意:索引定位是從1開始的
  • 取文本:
    /text():獲取的是標籤中直系文本內容
    //text():標籤中非直系的文本內容(全部的文本內容)
  • 取屬性:
    /@attrName:獲取某個屬性的值,好比://img/@src獲取任意的img標籤的src

3.2.3 使用例子

import requests
from lxml import etree
import re

headers={
        'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
    }
url="https://www.test.com/chaxun/zuozhe/77.html"


def getPoemsByXpath():
    res= requests.get(url=url,headers=headers)
    res.encoding='UTF-8'
    page_text=res.text
    #在首頁解析出章節
    tree = etree.HTML(page_text)
    shici_list = tree.xpath("//div[@class='shici_list_main']")
    shici_name_out=''
    for shici in shici_list:
        #此處使用相對路徑
        shici_name=shici.xpath("h3/a/text()")[0]
        # print(shici_name)
        shici_text_list=shici.xpath("div//text()")
        # print(shici_text_list)
        
        with open("./shicibyxpath.txt",'a+',encoding= 'utf8') as file:
            if shici_name_out!=shici_name:
                file.write(shici_name+"\n")

            for text in shici_text_list:
                if "展開全文"==text or "收起"==text or re.match(r'^\s*$',text)!=None or re.match(r'^\n\s*$',text)!=None:
                    continue
                re_text=text.replace(' ','').replace('\n','')
                file.write(re_text+"\n")
        if shici_name_out!=shici_name:
            print(shici_name+"下載完成!!!!")        
        shici_name_out=shici_name
    
        

if __name__=="__main__":
    getPoemsByXpath()
相關文章
相關標籤/搜索