爬虫快速上手之requests模块、互联网图片抓取、xpath的使用

目录

一、requests模块

二、互联网图片抓取

三、xpath的使用

四、lxml解析库

五、综合案例


一、requests模块

1.res = requests.get(url, headers)
返回值res是requests.models.Response类对象

2.requests模块res属性 对应 urllib.request模块res的方法:

res.text -> res.read().decode('utf8)

tes.content -> res.read()

tes.status_code -> res.getcode()

res.url -> res.geturl()

二、互联网图片抓取

说明:

        图片、音频、视频在计算机中均已二进制方式存储

实现:

        找到所要抓取图片的url地址

        向图片的url地址发请求,获取二进制响应内容(bytes)

        正常打开文件,将响应内容以wb方式保存至本地

三、xpath的使用

1.注意:

        只要涉及到条件,加[ ]://li[@class='xxx']    //li[2]

        只要获取属性值,加@://li[@class='xxx']    //li/@href

2.//:从所有节点中查找(包括子节点和后代节点)

3.@:获取属性值

        使用场景1(属性值作为条件)://div[@class='xxx']

        使用场景2(直接获取属性值)://div[@class='xxx']/a/img/@src

4.匹配多路径(或)

        xpath表达式1 | xpath表达式2 | xpath表达式3

5.contains():匹配属性值中包含某些字符串节点

        查找id属性值中包含字符串"car_"的li节点

        //li[contains(@id, "car_")]

6.text():获取节点的文本内容

        查找所有汽车的价格

        //ul[@class='CarList']/li/p[@class='price']/text()

7.总结

        使用xpath表达式匹配结果为两种情况:字符串和节点对象,解析如下:

        (1)xpath表达式的末尾为:/text()、/@href        得到的列表中为字符串

        (2)其他剩余所有情况得到的列表中均为 节点对象 

四、lxml解析库

1.安装

        Ubuntu:sudo pip3 install lxml

        Windows:python -m pip install lxml

2.使用流程

        导模块:from lxml import etree

        创建解析对象:parse_html = etree.HTML(html)

        解析对象调用xpath:r_list = parse_html.xpath('xpath表达式')

3.注意

        只要使用了xpath,则得到的数据类型一定为 列表 类型

五、综合案例

        百度贴吧图片抓取

        目标:抓取指定贴吧的所有帖子中的图片

        程序运行效果:

        请输入贴吧名:赵丽颖

        请输入起始页:1

         请输入终止页:2

        则程序将抓取赵丽颖吧前2页的所有帖子中的所有图片到本地当前目录

        代码如下:

from urllib import parse
import requests
from lxml import etree
import os
import time
import random

class TieBaImg(object):
    def __init__(self):
        self.word = input('请输入贴吧名:')
        self.start = input('请输入起始页:')
        self.end = input('请输入终止页:')
        self.url = 'https://tieba.baidu.com/f?kw={}&pn={}'
        self.filename = './tieba_images/{}/'.format(self.word)
        self.page = int(self.start) # 记录当前抓取的第几页数据
        self.link_count = 1 # 记录当前抓取页面第几个链接
        self.img_count = 1 # 记录一个链接里抓取的图片数目
        # if not os.path.exists(filename):
        #     os.makedirs(filename)
        # self.file = open(filename, 'wb')

    def get_html(self, url):
        """
        功能函数:获取网页源码html
        :param url:
        :return:
        """
        headers = {'User-Agent':'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E)'}
        html = requests.get(url=url, headers=headers).text
        return html

    def get_href(self, html, x):
        """
        功能函数:使用xpath,获取html中所需要的链接
        :param html:
        :return:
        """
        parse_html = etree.HTML(html) # 创建解析对象
        href_list = parse_html.xpath(x)
        return href_list

    def parse_data(self):
        """
        功能函数:解析数据
        :return:
        """
        word = parse.quote(self.word) # 将输入的关键字转为url编码
        first_x = '//ul[@id="thread_list"]//div[@class="threadlist_title pull_left j_th_tit "]/a/@href'
        second_x = '//div[@class="d_post_content_main d_post_content_firstfloor"]//img/@src'
        for i in range(int(self.start), int(self.end) + 1):
            url = self.url.format(word, (i-1)*50)
            first_html = self.get_html(url)
            # print(first_html)
            href_list = self.get_href(first_html, first_x) # 获取一级页面中二级页面的链接
            # print(href_list)
            time.sleep(random.uniform(1, 8)) # 每发起一次请求随机休眠的时间
            for href in href_list:
                second_url = 'https://tieba.baidu.com{}'.format(href) # 二级页面的链接
                second_html = self.get_html(second_url)
                src_list = self.get_href(second_html, second_x)
                # print(src_list)
                for src in src_list:
                    direct = '{}page_{}link_{}/'.format(self.filename, self.page, self.link_count)
                    self.save_img(direct, src) # 保存一张图片到本地
                    print('成功保存第 {} 页链接 {} 的图片 {} '.format(self.page, self.link_count, self.img_count))
                    self.img_count += 1
                self.link_count += 1
                self.img_count = 1 # 图片数量重至1
                time.sleep(random.uniform(1, 8)) # 每发起一次请求随机休眠的时间
            self.page += 1


    def save_img(self, filename, url):
        """
        功能函数:保存一张图片至本地
        :param url:
        :return:
        """
        if not os.path.exists(filename):
            os.makedirs(filename)
        headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'}
        img_b = requests.get(url=url, headers=headers).content # 获取图片的字节编码
        with open('{}img_{}.jpg'.format(filename, self.img_count), 'wb') as f:
            f.write(img_b)

if __name__ == '__main__':
    img = TieBaImg()
    img.parse_data()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值