爬蟲(2)——requests以及xpath的使用


一、requests

requests.request(method,url,**kwargs)

# 常見參數
# params/data/json  上傳數據
# files  上傳文件
# headers/cookies
# proxies 
# auth  授權

1、get請求

response = requests.get(url)

1)定制參數

參數使用params傳遞,注意:不需要urlencode

data = {"wd": “北京”}
response = request.get(url, params=data)

2)獲取網站源碼

response.text

3)訪問或定制的編碼

response.encoding = 'utf-8'

4)獲取請求的url

response.url 獲取請求的url

5)響應的字節類型

response.content

6)響應的狀態碼

response.status_code

7)響應的頭信息

response.headers

8)獲取json數據

response.json()  # 反序列化,將json數據轉換為python中的列表或字典

2、post請求

response = requests.post(uri, data=data) #data上傳的參數無需urlencode

3、headers定制

同urllib.request的頭定制

ua可以使用第三方包

from fake_useragent import UserAgent

ua = UserAgent().random

4、proxy定制

在請求中設置proxies參數,參數類型是一個字典類型

import requests

from fake_useragent import UserAgent

url = 'http://www.baidu.com/s'

headers = {
    'user-agent': UserAgent().random
}
data = {
    'wd':'ip'
  }
proxy = {
    'http':'219.149.59.250:9797'
}
r = requests.get(url=url,params=data,headers=headers,proxies=proxy)

with open('proxy.html','w',encoding='utf-8') as fp:
    fp.write(r.text)

5、cookie定制

s = requests.session()

1)方法

s.get()  
s.post()
s.put()
s.delete()
s.patch()
s.close()  # 關閉會話
s.cookies  # 獲取cookies  

二、xpath

1、xpath語法

XPath 是一門在 XML 文檔中查找信息的語言。XPath 用於在 XML 文檔中通過元素和屬性進行導航。

1)路徑查詢

/ 查找子節點,HTML中從<html>開始的  /html/title/text()

// 查找所有子孫節點,不考慮層級關系 如://title/text()

./a/@href 當前路徑下的a元素的href屬性,如/html -> Element , ./title/text()

../span/text() 父級下的span的文本內容

擴展:使用*通配符 /* 任意一個子節點,//*任意一個孫子節點

2)謂詞查詢

//div[@id] 查找所有包含id屬性的div節點

//div[@id="maincontent"]  查詢id屬性為maincontent的div的標簽

3)屬性查詢

//@class 查詢帶有class屬性的所有標簽

4)邏輯運算

//div[@id="head" and @class="s_down"] 查找所有id屬性等於head並且class屬性等於s_down的div標簽 (多個條件,and且的關系,or或的關系)

//title | //price 同時獲取title和price兩個標簽,| 前后的兩個是完整且獨立的xpath路徑

5)模糊查詢

//div[contains(@id, "he")]  查詢所有id屬性中包含he的div標簽

//div[starts-with(@id, "he")]  查詢所有id屬性中包以he開頭的div標簽

//div[ends-with(@id, "he")]  查詢所有id屬性中包以he結尾的div標簽

//ul/li[last()]/a/@href  ul中最后一個li內的a元素的href屬性值

6)內容查詢

//div/h1/text() 查找所有div標簽下的直接子節點h1的內容

2、xpath使用

1)安裝lxml庫

pip install lxml 

2)安裝xpath插件(調試方便,非必須)

chrome 安裝xpath helper,ctrl+shift+x 打開控制台,Shift+選擇網頁內容

3)導入lxml.etree

from lxml import etree

4)etree.parse()

html_tree = etree.parse('XX.html')  # 解析本地html文件

5)etree.HTML()

html_tree = etree.HTML(rsponse.read().decode('utf-8')  # 解析網絡的html字符串

6)html_tree.xpath()

xpath()返回是一個list列表

xpath返回的Element,可以看成是一個字典

 

三、爬取古詩文網

1、獲取古詩文網推薦頁所有的詩詞

import os
import time
from csv import DictWriter
from random import random

import requests
from lxml import etree

from fake_useragent import UserAgent


has_header = os.path.exists("gushiwen.csv")  # 是否第一次寫入csv的頭
header_fields = ('title', 'author', 'content')


def itemipeline4csv(item): # 保存數據
    global has_header
    with open('gushiwen.csv', 'a') as f:
        writer = DictWriter(f, header_fields)
        if not has_header:
            writer.writeheader()  # 寫入第一行標題
            has_header = True

        writer.writerow(item)  # 寫入數據



def parse(html):
    root = etree.HTML(html)
    divs = root.xpath("//div[@class='left']/div[@class='sons']")
    item = {}
    for div in divs:
        item["title"] = div.xpath(".//p[1]//text()")[0]
        item["author"] = " ".join(div.xpath(".//p[2]/a/text()"))
        item["content"] = div.xpath(".//div[@class='contson']//text()")
        itemipeline4csv(item)


def get(url):
    resp = requests.get(url, headers={'User-Agent': UserAgent().random})
    if resp.status_code == 200:
        parse(resp.text)
    else:
        raise Exception("請求失敗")


if __name__ == '__main__':
    for i in range(1, 11):
        time.sleep(random())
        get("https://www.gushiwen.org/default_%s.aspx" % i)
 

2、通過登錄,獲取收藏的古詩文

補充:雲打碼使用了超級鷹第三方,注冊賬號重置,簡單的修改,最后調用read_code()方法獲取驗證碼的字符串

import requests
from hashlib import md5

class Chaojiying_Client(object):

    def __init__(self, username, password, soft_id):
        self.username = username
        password =  password.encode('utf8')
        self.password = md5(password).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }

    def PostPic(self, im, codetype):
        """
        im: 圖片字節
        codetype: 題目類型 參考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
        return r.json()

    def ReportError(self, im_id):
        """
        im_id:報錯題目的圖片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()


def read_code(filename):
    chaojiying = Chaojiying_Client('huiyichanmian', 'christian825', '903878')  # 用戶中心>>軟件ID 生成一個替換 96001
    im = open(filename, 'rb').read()  # 本地圖片文件路徑 來替換 a.jpg 有時WIN系統須要//
    ret = chaojiying.PostPic(im, 8001)
    return ret['pic_str']
超級鷹接口代碼
"""
1、下載驗證碼的圖片
2、圖片驗證碼的打碼
3、登錄
4、獲取個人的收藏信息
"""
import requests


from lxml import etree
from fake_useragent import UserAgent


# 創建一個session對象
from day2.chaojiying import read_code

session = requests.session()  # 獲取驗證碼的接口和登錄的接口必須在同一個session中請求


def download_code():
    resp = session.get('https://so.gushiwen.org/RandCode.ashx', headers={'User-Agent': UserAgent(verify_ssl=False).random})
    with open("code.png", 'wb') as f:
        f.write(resp.content)


def get_code_str():
    download_code()
    return read_code("code.png")


def login():
    resp = session.post("https://so.gushiwen.org/user/login.aspx",
         data={
             'email': 'huiyichanmian@yeah.net',
             'pwd': 'christian825',
             'code': get_code_str()
         })
    if resp.status_code == 200:
        collect()
    else:
        print("-"*30)
        print(resp.text)


def collect():
    resp = session.get('https://so.gushiwen.org/user/collect.aspx')
    parse(resp.text)


def parse(html):
    root = etree.HTML(html)
    divs = root.xpath("//div[@class='left']/div[@class='sons']")
    item = {}
    for div in divs:
        item["title"] = div.xpath(".//p[1]//text()")[0]
        item["author"] = " ".join(div.xpath(".//p[2]/a/text()"))
        item["content"] = div.xpath(".//div[@class='contson']//text()")
        print(item)


if __name__ == '__main__':
    login()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM