网络请求库requests及数据解析xpath

本文介绍requests库的基础用法及XPath解析技术,并通过实例演示如何抓取豆瓣电影数据及古诗文网的内容并导出为CSV文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

requests库

requests库也是一个网络请求库, 基于urllib和urllib3封装的便捷使用的网络请求库。

安装环境

pip install requests -i https://mirrors.aliyun.com/pypi/simple

核心的函数

  • requests.request() 所有请求方法的基本方法

    以下是request()方法的参数说明

    • method: str 指定请求方法, GET, POST, PUT, DELETE

    • url: str 请求的资源接口(API),在RESTful规范中即是URI(统一资源标签识符)

    • params: dict , 用于GET请求的查询参数(Query String params);

    • data: dict , 用于POST/PUT/DELETE 请求的表单参数(Form Data)

    • json: dict 用于上传json数据的参数, 封装到body(请求体)中。请求头的Content-Type默认设置为application/json

    • files: dict, 结构 {‘name’: file-like-object | tuple}, 如果是tuple, 则有三种情况:

      • (‘filename’, file-like-object)
      • (‘filename’, file-like-object, content_type)
      • (‘filename’, file-like-object, content_type, custom-headers)

      指定files用于上传文件, 一般使用post请求,默认请求头的Content-Typemultipart/form-data类型。

    • headers/cookies : dict

    • proxies: dict , 设置代理

    • auth: tuple , 用于授权的用户名和口令, 形式(‘username’, ‘pwd’)

  • requests.get() 发起GET请求, 查询数据

    可用参数:

    • url
    • params
    • json
    • headers/cookies/auth
  • requests.post() 发起POST请求, 上传/添加数据

    可用参数:

    • url
    • data/files
    • json
    • headers/cookies/auth
  • requests.put() 发起PUT请求, 修改或更新数据

  • requests.patch() HTTP幂等性的问题,可能会出现重复处理, 不建议使用。用于更新数据

  • requests.delete() 发起DELETE请求,删除数据

requests.Respose

以上的请求方法返回的对象类型是Response, 对象常用的属性如下:

  • status_code 响应状态码

  • url 请求的url

  • headers : dict 响应的头, 相对于urllib的响应对象的getheaders(),但不包含cookie。

  • cookies: 可迭代的对象,元素是Cookie类对象(name, value, path)

  • text : 响应的文本信息

  • content: 响应的字节数据

  • encoding: 响应数据的编码字符集, 如utf-8, gbk, gb2312

  • json(): 如果响应数据类型为application/json,则将响应的数据进行反序化成python的list或dict对象。

    • 扩展-javascript的序列化和反序列化
      • JSON.stringify(obj) 序列化
      • JSON.parse(text) 反序列化

requests库小练习

"""
spider_02_requests_request.py
"""

import  requests
from requests import Response

def get_douban_movie():

    base_url='https://movie.douban.com/j/chart/top_list'
    params={
        'type' : 5 ,
        'interval_id': '100:90'  ,
         'action' : ''
    }

    data = {
        'start' : 0,
         'limit' : 20
    }

    headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36'
    }

    resp=requests.post(url=base_url,params=params,data=data,headers=headers)
    assert resp.status_code==200
    print(resp.url)
    if 'application/json' in resp.headers['Content-Type']:
        return resp.json()
    else:
        return resp.text

def get_anjuke():
    """
    有反爬虫
    """
    url='https://nc.anjuke.com/community/'

    params={
    'from':'navigation'
    }
    resp=requests.get(url=url,params=params)
    assert resp.status_code==200
    print(resp.content.decode('utf-8'))




if __name__ == '__main__':
    resp=get_douban_movie()
    print(resp)
    # get_anjuke() //有反爬虫

数据解析方式之xpath

xpath属于xml/html解析数据的一种方式, 基于元素(Element)的树形结构(Node > Element)。选择某一元素时,根据元素的路径选择,如 /html/head/title获取<title>标签。

安装xpath库

安装包 pip install lxml

引用 form lxml import etree

root=etree.HTML(html)

divs =root.xpath()

绝对路径

从根标签开始,按tree结构依次向下查询。

如 /html/body/table/tbody/tr。

相对路径

相对路径可以有以下写法

  • 相对于整个文档

    //img
    

    查找出文档中所有的<img>标签元素

  • 相对于当前节点

    //table
    

    假如当前节点是<table>, 查找它的<img>的路径的写法

    .//img
    

数据提取

  • 提取文本

    //title/text()
    
  • 提取属性

    //img/@href
    

位置条件

获取网页中的数据类型与字符集, 获取第一个<meta>标签

//meta[1]//@content

获取最后一个<meta>标签

//meta[last()]//@content

获取倒数第二个<meta>标签

//meta[position()-2]//@content

获取前三个<meta>标签

//meta[position()<3]//@content

属性条件

查找 class为circle-img<img>标签

//img[@class="circle-img"]

同时提取两个元素

  • //title/text() | //img/@src

模糊条件

  • //div[contains(@class, "page")] 查找class属性包含page的所有div标签
  • //div[starts-with(@class, "box")] 第一个class的属性值为box的div标签
  • //div[ends-with(@class, "clearfix")]最一个class的属性值为clearfix的div标签

xpath小练习

# spider_02_requests_xpath.py
"""
request发起网络请求
xpath进行数据解析
"""
import  requests
from lxml import  etree



header={
    'User-Agent' :'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36'
}
# proxy={
#     'http':'http://120.220.220.95:8085'
# }

def  get_request(url):
    resp=requests.get(url,headers=header)
    if resp.status_code==200:
        parse_html(resp.text)
    else:
        print("请求失败!")

def parse_html(html):
    root=etree.HTML(html)
    divs= root.xpath('//div[@class="left"]/div[@class="sons"]') # list[<Element>, ..]
    print(divs)
    for div in divs:
        title=div.xpath('.//div[@class="cont"]/p[1]/a/b/text()')
        author=div.xpath('.//div[@class="cont"]/p[2]/a/text()')
        content=div.xpath('.//div[@class="cont"]/div[@class="contson"]/text()')
        print(title,author,content)




if __name__ == '__main__':
    get_request('https://www.gushiwen.cn/')


xpath编写小妙招

有的时候自己审查,编写表达式,有一点点的小麻烦,比较快速的方法,就是直接选中目标元素,右键选择Copy,找到Copy Xpath/Copy full Xpath,作为参考,就能很快写出符合自身的表达式。

Copy Xpath

  • //*[@id="leftZhankai"]/div[2]/div[1]/p[1]/a/b

Copy full Xpath

  • /html/body/div[2]/div[1]/div[2]/div[2]/div[1]/p[1]/a/b

导出csv文件小练习


"""
抓取信息导出CSV文件

"""
import  requests
import uuid
import  os
from lxml import  etree
from csv import DictWriter

header={
    'User-Agent' :'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36'
}
params={
    'page':''
}

def get_request(pages):
    url='https://so.gushiwen.cn/shiwens/default.aspx?'
    for page in range(1,pages+1):
        params['page']=page
        resp = requests.get(url, headers=header,params=params)
        print('正在获取第 %s 页诗词!' %page)
        if resp.status_code == 200:
            parse_html(resp.text)
        else:
            print("请求失败!")


def parse_html(html):
    root = etree.HTML(html)
    # pages=root.xpath('/html/body/div[2]/div[1]/div[2]/form/div/label[2]/text()')
    # pages=int(pages[0])
    # print(pages)
    divs = root.xpath('//div[@class="left"]/div[@id="leftZhankai"]/div[@class="sons"]')  # list[<Element>, ..]
    print(divs)
    item={}
    for div in divs:
       item['id'] = uuid.uuid4().hex
       item['title'] =div.xpath('.//div[@class="cont"]/p[1]/a/b/text()')[0]
       item['author']= ''.join(div.xpath('.//div[@class="cont"]/p[2]/a/text()'))
       item['content'] = ''.join(div.xpath('.//div[@class="cont"]/div[@class="contson"]/text()'))
       itempipe4csv(item)

has_header = os.path.exists('dushuwang.csv')  # 是否第一次写入csv的头
header_fields = ('id', 'title', 'author', 'content')

def itempipe4csv(item):
    print(item)
    global has_header
    with open('dushuwang.csv', 'a', encoding='utf-8',newline='') as f:
        #newline='' 解决CSV换行问题
        writer = DictWriter(f, fieldnames=header_fields)
        if not has_header:
            writer.writeheader()  # 写入第一行的标题
            has_header = True

        writer.writerow(item)  # 写入数据

if __name__ == '__main__':
    get_request(5)
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值