1. 程式人生 > >Python系統學習-27

Python系統學習-27

http://www.xiaobaibook.com/details/52/

https://www.cnblogs.com/bobo-zhang/-------爬蟲老師

  1. 爬蟲開發基礎
    1.1為什麼要使用requests模組
    因為在使用urllib模組的時候,會有諸多不便之處,總結如下:
    手動處理url編碼
    手動處理post請求引數
    處理cookie和代理操作繁瑣

    使用requests模組:
    自動處理url編碼
    自動處理post請求引數
    簡化cookie和代理操作

1.2資料爬取的流程:

  • 指定url
  • 基於requests模組發起請求
  • 獲取響應中的資料
  • 資料解析
  • 進行持久化儲存

1.3三種資料解析方式:

  • 正則表示式
  • xpath
  • BeautifulSoup解析

1.4Xpath
屬性定位:
#找到class屬性值為song的div標籤
//div[@class=“song”]
層級&索引定位:
#找到class屬性值為tang的div的直系子標籤ul下的第二個子標籤li下的直系子標籤a
//div[@class=“tang”]/ul/li[2]/a
邏輯運算:
#找到href屬性值為空且class屬性值為du的a標籤
//a[@href="" and @class=“du”]
模糊匹配:
//div[contains(@class, “ng”)]
//div[starts-with(@class, “ta”)]
取文字:


# /表示獲取某個標籤下的文字內容
# //表示獲取某個標籤下的文字內容和所有子標籤下的文字內容
//div[@class=“song”]/p[1]/text()
//div[@class=“tang”]//text()
取屬性:
//div[@class=“tang”]//li[2]/a/@href

1.4.1Xpath例項
1.下載:pip install lxml
2.導包:from lxml import etree

3.將html文件或者xml文件轉換成一個etree物件,然後呼叫物件中的方法查詢指定的節點

2.1 本地檔案:tree = etree.parse(檔名)
tree.xpath(“xpath表示式”)

2.2 網路資料:tree = etree.HTML(網頁內容字串)
tree.xpath(“xpath表示式”)
安裝xpath外掛在瀏覽器中對xpath表示式進行驗證:可以在外掛中直接執行xpath表示式
將xpath外掛拖動到谷歌瀏覽器拓展程式(更多工具)中,安裝成功

啟動和關閉外掛 ctrl + shift + x

專案需求:獲取好段子中段子的內容和作者 http://www.haoduanzi.com

from lxml import etree
import requests

url=‘http://www.haoduanzi.com/category-10_2.html
headers = {
‘User-Agent’: ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36’,
}
url_content=requests.get(url,headers=headers).text
#使用xpath對url_conten進行解析
#使用xpath解析從網路上獲取的資料
tree=etree.HTML(url_content)
#解析獲取當頁所有段子的標題
title_list=tree.xpath(’//div[@class=“log cate10 auth1”]/h3/a/text()’)

ele_div_list=tree.xpath(’//div[@class=“log cate10 auth1”]’)

text_list=[] #最終會儲存12個段子的文字內容
for ele in ele_div_list:
#段子的文字內容(是存放在list列表中)
text_list=ele.xpath(’./div[@class=“cont”]//text()’)
#list列表中的文字內容全部提取到一個字串中
text_str=str(text_list)
#字串形式的文字內容防止到all_text列表中
text_list.append(text_str)
print(title_list)
print(text_list)

1.5Beautiful soap

  • 需要將pip源設定為國內源,阿里源、豆瓣源、網易源等
    • windows
      (1)開啟檔案資源管理器(資料夾位址列中)
      (2)位址列上面輸入 %appdata%
      (3)在這裡面新建一個資料夾 pip
      (4)在pip資料夾裡面新建一個檔案叫做 pip.ini ,內容寫如下即可
      [global]
      timeout = 6000
      index-url = https://mirrors.aliyun.com/pypi/simple/
      trusted-host = mirrors.aliyun.com
    • linux
      (1)cd ~
      (2)mkdir ~/.pip
      (3)vi ~/.pip/pip.conf
      (4)編輯內容,和windows一模一樣
  • 需要安裝:pip install bs4
    bs4在使用時候需要一個第三方庫,把這個庫也安裝一下
    pip install lxml
    基礎使用

使用流程:
- 導包:from bs4 import BeautifulSoup
- 使用方式:可以將一個html文件,轉化為BeautifulSoup物件,然後通過物件的方法或者屬性去查詢指定的節點內容
(1)轉化本地檔案:
- soup = BeautifulSoup(open(‘本地檔案’), ‘lxml’)
(2)轉化網路檔案:
- soup = BeautifulSoup(‘字串型別或者位元組型別’, ‘lxml’)
(3)列印soup物件顯示內容為html檔案中的內容

基礎鞏固:
(1)根據標籤名查詢
- soup.a 只能找到第一個符合要求的標籤
(2)獲取屬性
- soup.a.attrs 獲取a所有的屬性和屬性值,返回一個字典
- soup.a.attrs[‘href’] 獲取href屬性
- soup.a[‘href’] 也可簡寫為這種形式
(3)獲取內容
- soup.a.string
- soup.a.text
- soup.a.get_text()
【注意】如果標籤還有標籤,那麼string獲取到的結果為None,而其它兩個,可以獲取文字內容
(4)find:找到第一個符合要求的標籤
- soup.find(‘a’) 找到第一個符合要求的
- soup.find(‘a’, title=“xxx”)
- soup.find(‘a’, alt=“xxx”)
- soup.find(‘a’, class_=“xxx”)
- soup.find(‘a’, id=“xxx”)
(5)find_all:找到所有符合要求的標籤
- soup.find_all(‘a’)
- soup.find_all([‘a’,‘b’]) 找到所有的a和b標籤
- soup.find_all(‘a’, limit=2) 限制前兩個
(6)根據選擇器選擇指定的內容
select:soup.select(’#feng’)
- 常見的選擇器:標籤選擇器(a)、類選擇器(.)、id選擇器(#)、層級選擇器
- 層級選擇器:
div .dudu #lala .meme .xixi 下面好多級
div > p > a > .lala 只能是下面一級
【注意】select選擇器返回永遠是列表,需要通過下標提取指定的物件
需求:使用bs4實現將詩詞名句網站中三國演義小說的每一章的內容爬去到本地磁碟進行儲存 http://www.shicimingju.com/book/sanguoyanyi.html

import requests
from bs4 import BeautifulSoup

headers={
‘User-Agent’: ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36’,
}
def parse_content(url):
#獲取標題正文頁資料
page_text = requests.get(url,headers=headers).text
soup = BeautifulSoup(page_text,‘lxml’)
#解析獲得標籤
ele = soup.find(‘div’,class_=‘chapter_content’)
content = ele.text #獲取標籤中的資料值
return content

if name == “main”:
url = ‘http://www.shicimingju.com/book/sanguoyanyi.html
reponse = requests.get(url=url,headers=headers)
page_text = reponse.text

 #建立soup物件
 soup = BeautifulSoup(page_text,'lxml')
 #解析資料
 a_eles = soup.select('.book-mulu > ul > li > a')
 print(a_eles)
 cap = 1
 for ele in a_eles:
     print('開始下載第%d章節'%cap)
     cap+=1
     title = ele.string
     content_url = 'http://www.shicimingju.com'+ele['href']
     content = parse_content(content_url)

     with open('./sanguo.txt','w') as fp:
         fp.write(title+":"+content+'\n\n\n\n\n')
         print('結束下載第%d章節'%cap)

1.6requests模組的cookie和代理操作
‘’’
使用透明代理,對方伺服器可以知道你使用了代理,並且也知道你的真實IP。
使用匿名代理,對方伺服器可以知道你使用了代理,但不知道你的真實IP。
使用高匿名代理,對方伺服器不知道你使用了代理,更不知道你的真實IP
‘’’

import requests

headers = {
	'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
}
url = 'https://www.baidu.com/s?wd=ip'

page_text = requests.get(url=url, headers=headers, proxies={'https': '123.1.150.244:80'}).text
with open('./ip.html', 'w', encoding='utf-8') as fp:
	fp.write(page_text)
  • cookie概念:當用戶通過瀏覽器首次訪問一個域名時,訪問的web伺服器會給客戶端傳送資料,以保持web伺服器與客戶端之間的狀態保持,這些資料就是cookie。

  • cookie作用:我們在瀏覽器中,經常涉及到資料的交換,比如你登入郵箱,登入一個頁面。我們經常會在此時設定30天內記住我,或者自動登入選項。那麼它們是怎麼記錄資訊的呢,答案就是今天的主角cookie了,Cookie是由HTTP伺服器設定的,儲存在瀏覽器中,但HTTP協議是一種無狀態協議,在資料交換完畢後,伺服器端和客戶端的連結就會關閉,每次交換資料都需要建立新的連結。就像我們去超市買東西,沒有積分卡的情況下,我們買完東西之後,超市沒有我們的任何消費資訊,但我們辦了積分卡之後,超市就有了我們的消費資訊。cookie就像是積分卡,可以儲存積分,商品就是我們的資訊,超市的系統就像伺服器後臺,http協議就是交易的過程。

  • 經過cookie的相關介紹,其實你已經知道了為什麼上述案例中爬取到的不是張三個人資訊頁,而是登入頁面。那應該如何抓取到張三的個人資訊頁呢?

思路:

1.我們需要使用爬蟲程式對人人網的登入時的請求進行一次抓取,獲取請求中的cookie資料

2.在使用個人資訊頁的url進行請求時,該請求需要攜帶 1 中的cookie,只有攜帶了cookie後,伺服器才可識別這次請求的使用者資訊,方可響應回指定的使用者資訊頁資料

import requests
if __name__ == "__main__":

    #登入請求的url(通過抓包工具獲取)
    post_url = 'http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=201873958471'
    #建立一個session物件,該物件會自動將請求中的cookie進行儲存和攜帶
    session = requests.session()
   #偽裝UA
    headers={
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
    }
    formdata = {
        'email': '17701256561',
        'icode': '',
        'origURL': 'http://www.renren.com/home',
        'domain': 'renren.com',
        'key_id': '1',
        'captcha_type': 'web_login',
        'password': '7b456e6c3eb6615b2e122a2942ef3845da1f91e3de075179079a3b84952508e4',
        'rkey': '44fd96c219c593f3c9612360c80310a3',
        'f': 'https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3Dm7m_NSUp5Ri_ZrK5eNIpn_dMs48UAcvT-N_kmysWgYW%26wd%3D%26eqid%3Dba95daf5000065ce000000035b120219',
    }
    #使用session傳送請求,目的是為了將session儲存該次請求中的cookie
    session.post(url=post_url,data=formdata,headers=headers)

    get_url = 'http://www.renren.com/960481378/profile'
    #再次使用session進行請求的傳送,該次請求中已經攜帶了cookie
    response = session.get(url=get_url,headers=headers)
    #設定響應內容的編碼格式
    response.encoding = 'utf-8'
    #將響應內容寫入檔案
    with open('./renren.html','w') as fp:
        fp.write(response.text)

1.7selenuim和phantonJs處理網頁動態載入資料的爬取

-為什麼使用selenium在爬蟲中?
因為有些資料是懶載入,只有執行某些操作後才能載入資料,所以需要selenium。

1.7.1phantomJs

  • PhantomJS是一款無介面的瀏覽器,其自動化操作流程和上述操作谷歌瀏覽器是一致的。由於是無介面的,為了能夠展示自動化操作流程,PhantomJS為使用者提供了一個截圖的功能,使用save_screenshot函式實現。

  • 重點(phantomjs已經不維護):selenium+phantomjs 就是爬蟲終極解決方案:有些網站上的內容資訊是通過動態載入js形成的,所以使用普通爬蟲程式無法回去動態載入的js內容。例如豆瓣電影中的電影資訊是通過下拉操作動態載入更多的電影資訊

1.8谷歌無頭瀏覽器

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
 
# 建立一個引數物件,用來控制chrome以無介面模式開啟
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
# 驅動路徑
path = r'C:\Users\ZBLi\Desktop\1801\day05\ziliao\chromedriver.exe'
 
# 建立瀏覽器物件
browser = webdriver.Chrome(executable_path=path, chrome_options=chrome_options)
 
# 上網
url = 'http://www.baidu.com/'
browser.get(url)
time.sleep(3)
 
browser.save_screenshot('baidu.png')
 
browser.quit()