CSS选择器

什么是CSS选择器?

  • CSS(Cascading Style Sheets)是一种语言,它被用来描述 HTML 和 XML 文档的表现。
  • CSS使用选择器来为页面元素绑定属性。

CSS 选择器常用语法:

表达式匹配结果
* 通用元素选择器匹配任何元素
E 标签选择器匹配所有使用 E 标签的元素
.info class 选择器匹配所有 class 属性中包含 info 的元素
#footer id 选择器匹配所有 id 属性等于 footer 的元素
E,F 多元素选择器同时匹配所有 E 元素或 F 元素,E 和 F 之间用逗号分隔
E F 后代元素选择器匹配所有属于 E 元素后代的 F 元素,E 和 F 之间用空格分隔
E > F 子元素选择器匹配所有 E 元素的子元素 F
E + F 毗邻元素选择器匹配紧随 E 元素之后的同级元素 F (只匹配第一个)
E ~ F 同级元素选择器匹配所有在 E 元素之后的同级 F 元素
E[att=‘val’]属性 att 的值为 val 的 E 元素
E[att^=‘val’]属性 att 的值以 val 开头的 E 元素
E[att$=‘val’]属性 att 的值以 val 结尾的 E 元素
E[att*=‘val’]属性 att 的值包含 val 的 E 元素
E[att1=‘v1’][att2*=‘v2’]属性 att1 的值为 v1,att2 的值包含 v2
E:contains(‘xxxx’)内容中包含 xxxx 的 E 元素
E:not(s)匹配不符合当前选择器的任何元素


PyQuery 的使用

在 Python中,PyQuery、Selenium、Scrapy 等库可用 CSS 选择器作为定位策略。这里以 PyQuery 为例。


(1) PyQuery 使用 CSS 选择器作为元素定位

from pyquery import PyQuery


"""初始化url"""
doc = PyQuery('https://www.baidu.com', encoding='utf8')

# 通过标签名获取元素
print(doc('title'))

# 通过id属性值获取元素
print(doc('#su'))

# 通过class属性值获取元素
print(doc('.s_ipt'))

# 通过其他属性值获取元素
print(doc('[type="submit"]'))
print(doc('[name="wd"]'))

# 组合定位
print(doc('input.s_ipt'))
print(doc('[value="百度一下"][type="submit"]'))

# 子元素选择器
print(doc('#u1>a'))

# 后代选择器
print(doc('#u1 a'))

# 获取同级元素后面的第一个元素
print(doc('a[name="tj_trnews"]+a'))

# 获取同级元素后面的所有元素
print(doc('a[name="tj_trnews"]~a'))


(2) PyQuery 的结构性定位

from pyquery import PyQuery


doc = PyQuery('https://www.baidu.com', encoding='utf8')

# 获取a元素集合中的第一个
print(doc('#u1>a:first'))


# 获取a元素集合中的第三个
print(doc('#u1>a:eq(2)'))


# 获取a元素集合中的最后一个
print(doc('#u1>a:last'))


# 获取a元素集合中排在第三位之前的所有a元素
print(doc('#u1>a:lt(2)'))


# 获取a元素集合中排在第三位之后的所有a元素
print(doc('#u1>a:gt(2)'))


(3) PyQuery 提取元素中的内容

from pyquery import PyQuery


doc = PyQuery('https://www.baidu.com', encoding='utf8')

'''获取元素中的文本'''
print(doc('title').text())
# >>> 百度一下,你就知道

'''获取元素中的属性值'''
print(doc('#su').attr('value'))
# print(doc('#su').attr.value) 同上
# >>> 百度一下

print(type(doc('#u1>a')))
# >>> <class 'pyquery.pyquery.PyQuery'>

'''items() 方法可以将 PyQuery 对象变成生成器'''
els = doc('#u1>a').items()
print(type(els))
# >>> <class 'generator'>

'''遍历生成器,每个元素又是 PyQuery 对象'''
for el in els:
    print(type(el))
    # >>> <class 'pyquery.pyquery.PyQuery'>
    print(el.text())


(4) 下面用 PyQuery 解析数据的爬取图片例子:

from fake_useragent import UserAgent
from pyquery import PyQuery
import requests
import os
import re


def get_response(url, referer):
    """ 获取response响应内容 """
    headers = {'User-Agent': UserAgent().chrome, 'Referer': referer}
    response = requests.get(url, headers=headers, timeout=8)
    response.raise_for_status()
    return response


def crawler(url):
    """ 获取页面的套图链接、标题、套图数量 """
    page = get_response(url, url).text
    doc = PyQuery(page)
    lis = doc('#pins>li>a').items()
    for li in lis:
        href = li.attr('href')
        html = get_response(href, href).text
        d = PyQuery(html)
        # 返回提取的数据
        src = d('div.main-image a>img').attr('src')
        alt = d('div.main-image a>img').attr('alt')
        num = d('div.pagenavi>a:eq(4)').text()
        yield (href, src, alt, num)


def process(items):
    """处理数据 """
    for item in items:
        href, src, alt, num = item
        alt = re.sub(r'\W+', '_', alt)  # 更换标题的特殊字符
        # 创建存放每个套图的目录
        global path
        path = './image/' + alt
        if not os.path.exists(path):
            os.makedirs(path)
        # 封装数据
        for n in range(1, int(num) + 1):
            p = str(n) if n > 9 else f'0{n}'  # 处理图片序号
            img_url = src[:-6] + p + '.jpg'
            img_referer = href + '/' + f'{n}'
            img_name = alt + p
            yield (img_url, img_referer, img_name)


def download(images):
    """下载图片"""
    for image in images:
        img_url, img_referer, img_name = image
        content = get_response(img_url, img_referer).content
        with open(path + '/' + img_name + '.jpg', 'wb') as f:
            f.write(content)
            print('已下载', img_name + '.jpg')


if __name__ == '__main__':
    """要爬取的页面"""
    for i in range(1, 151):
        url = f'https://www.mzitu.com/xinggan/page/{i}/'
        try:
            """爬取页面的数据"""
            items = crawler(url)
            """处理数据"""
            images = process(items)
            """下载图片"""
            download(images)
        except:
            pass
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值