1. 程式人生 > >python 基礎 網路爬蟲 day06

python 基礎 網路爬蟲 day06

目錄

day05

1.json模組

  1. json.loads() json格式(物件,陣列) ->Python(字典,列表)
  2. json.dumps() Python(字典,元組,列表) -> json(物件,陣列)

2.Ajax動態載入

  1. 抓包工具抓引數:WebForms -> QueryString
  2. params = {QueryString中的一堆查詢引數}
  3. URL地址寫:抓包工具Raw下的GET地址

.3.selenium + phantomjs

  1. sekenium:Web自動化測試工具
  2. phantomjs:無介面瀏覽器(在記憶體執行頁面載入)
  3. 使用步驟
    1. 匯入模組 from selenium import webdriver from selenium.webdriver.common.keys import Keys
    2. 建立瀏覽器物件 driver = webdriver.PhantomJS(executable_path="...")
    3. 獲取網頁資訊 driver.get(url)
    4. 查詢節點位置  ele = driver.find_element_by_id("")
    5. 傳送文字 ele.send_keys("")
    6. 點選 cli = driver.find_element_by_class_name("") cli.click()
    7. 關閉 driver.quit()
  4. 常用方法
    1. driver.get(url)
    2. driver.page_source
    3. driver.page_source.find('字串') 失敗:-1 成功:非-1
    4. driver.find_element_by_name("屬性值")
    5. driver.find_elements_by_xpath("xpath表示式")
    6. 物件名.send_keys("")
    7. 物件名.click()
    8. 物件名.text
    9. driver.quit()

4.selenium + chromedriver

  1. chromedriver Chrome的 Webdriver
  2. 安裝
    1. 下載對應版本的chromedriver安裝包 https://chromedriver.storage.googleapis.com/index.html
    2. 將 chromedriver.exe 放到python安裝目錄的Scripts目錄
  3. 如何設定無介面模式 opt = webdriver.ChromeOptions() opt.set_headless() driver = webdriver.Chrome(options=opt) driver.get(...)
  4. driver如何執行JavaScript driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')

day06

1.多執行緒爬蟲

  1. 程序執行緒回顧
    1. 程序
      1. 系統中正在執行的一個應用程式
      2. 1個CPU核心1次只能執行1個程序,其他程序處於非執行狀態
      3. N個CPU核心可以同時執行N個任務
    2. 執行緒
      1. 程序中包含的執行單元,1個程序可包含多個執行緒
      2. 執行緒可使用所屬程序的空間(1次只能執行1個執行緒,阻塞)
      3. 鎖:防止多個執行緒同時使用共享空間
    3. GIL:全域性解釋鎖 執行通行證,僅此一個,拿到了通行證可執行,否則 等
    4. 應用場景
      1. 多程序:大量的密集的計算
      2. 多執行緒:I/O密集 爬蟲:網路I/O多,適合多執行緒 寫檔案:本地磁碟I/O
  2. 案例:使用多執行緒爬取 百思不得其解 段子
    1. 爬取目標:段子內容
    2. xpath表示式://div[@class="j-r-list-c-desc"]/a/text()
    3. 知識點
      1. 佇列(from queue import Queue) put() get() Queue.empty():是否為空 Queue.join():如果佇列為空,執行其他程式
      2. 執行緒(import threading) threading.Thread(target=...)
    4. 程式碼實現
      '''01_多執行緒爬取百思不得其姐案例.py'''
      import requests
      from lxml import etree
      from queue import Queue
      import threading
      import time
      
      class bsSpider:
          def __init__(self):
              self.baseurl = "http://www.budejie.com/"
              self.headers = {"User-Agent":"Mozilla/5.0"}
              # url佇列
              self.urlQueue = Queue()
              # 響應佇列
              self.resQueue = Queue()
                 
          # 生成URL佇列
          def getUrl(self):
              for pNum in range(1,51):
                  # 拼接URL
                  url = self.baseurl + str(pNum)
                  self.urlQueue.put(url)
          
          # 響應佇列
          def getHtml(self):
              while True:
                  url = self.urlQueue.get()
                  res = requests.get(url,headers=self.headers)
                  res.encoding = "utf-8"
                  html = res.text
                  # 放到響應佇列
                  self.resQueue.put(html)
                  # 清除此任務
                  self.urlQueue.task_done()         
                  
          # 解析頁面
          def getContent(self):
              while True:
                  # 從響應佇列中依次獲取html原始碼
                  html = self.resQueue.get()
                  parseHtml = etree.HTML(html)
                  r_list = parseHtml.xpath('//div[@class="j-r-list-c-desc"]/a/text()')
                  for r in r_list:
                      print(r+"\n")
                  # 清除任務
                  self.resQueue.task_done()
          
          def run(self):
              # 存放所有的執行緒
              thread_list = []
              # 獲取url佇列
              self.getUrl()
              # 建立getHtml執行緒
              for i in range(5):
                  threadRes = threading.Thread(target=self.getHtml)
                  thread_list.append(threadRes)
              
              # 解析執行緒
              for i in range(3):
                  threadParse = threading.Thread(target=self.getContent)
                  thread_list.append(threadParse)
                  
              # 所有執行緒開始幹活
              for th in thread_list:
                  th.setDaemon(True)
                  th.start()
              
              # 如果佇列為空,則執行其他程式
              self.urlQueue.join()
              self.resQueue.join()
              
              print("執行結束")
                  
      if __name__ == "__main__":
          begin = time.time()
          spider = bsSpider()
          spider.run()
          end = time.time()
          print(end-begin)
      

2.BeautifulSoup

  1. 定義 HTML或XML的解析器,依賴於1xml
  2. 安裝 python -m pip install beautifulsoup4 導模組:   from bs4 import BeautifulSoup
  3. 使用流程
    1. 匯入模組 from bs4 import BeautifulSoup
    2. 建立解析物件 soup = Beautifulsoup(html,'1xml')
    3. 查詢節點物件 soup.find_all(class="屬性值")
  4. 示例程式碼
    '''02_BeautifulSoup示例.py'''
    from bs4 import BeautifulSoup
    
    html = '<div class="test">雄霸</div>'
    # 建立解析物件
    soup = BeautifulSoup(html,'lxml')
    # 查詢節點
    #r_list = soup.find_all(class_="test")
    r_list = soup.find_all("div",attrs={"class":"test"})
    
    for r in r_list:
        print(r.get_text())
    '''03_BeautifulSoup示例2.py'''
    from bs4 import BeautifulSoup
    
    html = '''<div class="test">雄霸</div>
              <div class="test">幽若</div>
              <div class="test2">
                <span>第二夢</span>
              </div>
           '''
    soup = BeautifulSoup(html,'lxml')
    # class為test的div的文字內容
    #divs = soup.find_all("div",attrs={"class":"test"})
    for div in divs:
        print(div.string)
        print(div.get_text())
        
    # class為test2的div下的span中文字內容
    divs = soup.find_all("div",attrs={"class":"test2"})
    for div in divs:
        print(div.span.string)
  5. BeautifulSoup支援的解析庫
    1. lxml:BeautifulSoup(html,'1xml') 速度快,文件容錯力強
    2. python標準庫:BeautifulSoup(html,'html.parser') 速度一般
    3. xml解析器:BeautifulSoup(html,'xml') 速度快,文件容錯力強
  6. 節點選擇器
    1. 選擇節點 soup.節點名:soup.a 、soup.ul
    2. 獲取文字內容 soup.節點名.string
  7. 常用方法
    1. find_all():返回列表
      1. r_list = soup.find_all(屬性名="屬性值") r_list = soup.find_all(class_="test")
      2. r_list = soup.find_all('節點名',attrs={'名':'值'}) r_list = soup.find_all('div',attrs={"class":"test"})
    2. 示例:
      '''04_糗事百科BeautifulSoup.py'''
      import requests
      from bs4 import BeautifulSoup
      
      url = "https://www.qiushibaike.com/"
      headers = {"User-Agent":"Mozilla/5.0"}
      
      res = requests.get(url,headers=headers)
      res.encoding = "utf-8"
      html = res.text
      
      # 建立解析物件
      soup = BeautifulSoup(html,'lxml')
      r_list = soup.find_all("div",attrs={"class":"content"})
      
      for r in r_list:
          s = r.span.get_text().strip()
          print(s)
          print("*" * 30)

3.Scrapy框架

  1. 安裝
    1. 安裝(Ubuntu)
      1. 安裝依賴庫 sudo apt-get install python3-dev build-essential libssl-dev  libffi-dev libxml2 libxml2-dev libxslt1-dev zlib1g-dev
      2. 升級pyasn1模組 sudo pip3 install pyasn1==0.4.4
      3. 安裝Scrapy sudo pip3 install Scrapy

4.Scrapy框架

  1. Scrapy框架 非同步處理框架,可配置和可擴充套件程度非常高,Python中使用最廣泛的爬蟲框架
  2. 框架組成
    1. 引擎(Engine):整個框架核心
    2. 排程器(Scheduler):接受從引擎發過來的URL,入佇列
    3. 下載器(Downloads):下載網頁原始碼,最終返回給爬蟲程式
    4. 專案管道(Item Pipeline):資料處理
    5. 下載器中介軟體(Downloader Middlewares): 處理引擎與下載器之間的請求與響應
    6. 蜘蛛中介軟體(Spider Middlerwares): 處理爬蟲程式輸入響應和輸出結果以及新的請求
    7. Item:定義爬取結果的資料結構,爬取的資料會被賦值為Item物件
  3. Scrapy框架的爬取流程
  4. 製作Scrapy爬蟲專案步驟
    1. 新建專案 scrapy startproject 專案名
    2. 明確目標(items.py)
    3. 製作爬蟲程式 xxx/spiders:scrapy genspider 檔名 域名
    4. 處理資料(pipelines.py)
    5. 配置settings.py
    6. 執行爬蟲專案 scrapy crawl 爬蟲名
  5. scrapy專案檔案詳解
    1. 目錄結構
          testspider/
      	├── scrapy.cfg         #專案基本配置檔案,不用改
      	└── testspider
      	    ├── __init__.py
      	    ├── items.py       # 定義爬取資料的結構
      	    ├── middlewares.py # 下載器中介軟體和蜘蛛中介軟體實現
      	    ├── pipelines.py   # 處理資料
      	    ├── settings.py    # 專案全域性配置
      	    └── spiders        # 存放爬蟲程式
          		├── __init__.py
      	    	├── myspider.py
    2. settings.py配置
            # 是否遵守robots協議,該為False
            ROBOTSTXT_OBEY = False
      
            # 最大併發量,預設為16個
            CONCURRENT_REQUESTS = 32
      
            # 下載延遲時間為3秒
            DOWNLOAD_DELAY = 3
      
            # 請求報頭
            DEFAULT_REQUEST_HEADERS = {
              'User-Agent': "Mozilla/5.0",
               'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
               'Accept-Language': 'en',
              }
      
            # 蜘蛛中介軟體
            SPIDER_MIDDLEWARES = {
               'testspider.middlewares.TestspiderSpiderMiddleware': 543,
              }
      
            # 下載器中介軟體
            DOWNLOADER_MIDDLEWARES = {
               'testspider.middlewares.TestspiderDownloaderMiddleware': 543,
              }
      
            # 管道檔案
            ITEM_PIPELINES = {
               'testspider.pipelines.TestspiderPipeline': 300,
            }
    3. 示例:抓取百度首頁原始碼,存到baidu.html中
      1. scrapy startproject baidu
      2. cd baidu/baidu
      3. subl items.py(此示例可不用操作)
      4. cd spiders
      5. scrapy genspider baiduspider baidu.com #爬蟲名 #域名 #start_urls def parse(self,response):     with open('baidu.html','w') as f:         f.write(response.text)
      6. subl settings.py
        1. 關閉robots協議
        2. 新增Headers
      7. cd spiders
      8. scrapy crawl baiduspider

5.pycharm執行scrapy專案

  1. 建立檔案begin.py 和scrapy.cfg同目錄 from scrapy import cmdline cmdline.execute("scrapy crawl baiduspider".split())
  2. 在 Run -> Editconfigurations -> + -> python name : spider Script : begin.py的路徑 working directory : 你自己的專案路徑
  3. 開啟begin.py 右上角 - 點執行