Requests使用实例

之前写过一篇简单使用request的文章,这篇来写一些更有实用性一些的功能案例,需要结合使用re,bs4, xpath等。另外,上一篇仅仅是获取网页本身,而不涉及到媒体文件,比如图片,音频等等。

先来看看获取图片:

import urllib
url = 'http://duanziwang.com/usr/uploads/2019/02/3334500855.jpg'
urllib.request.urlretrieve(url=url,filename='./1.jpg')

urllib是requests是的早期版本,封装度相对更低一些,下载图片有urlretrieve方法:它有两个参数,第一个为图片的url,第二个为保存本地的文件名 

再来看看通过requests实现

import requests
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
}
url = 'http://duanziwang.com/usr/uploads/2019/02/3334500855.jpg'
pic_data = requests.get(url=url,headers=headers).content #content返回的是二进制类型的响应数据
with open('2.jpg','wb') as fp:
    fp.write(pic_data)

可以看到,获取图片是content属性,而非text

但也可以看到,urllib是直接获取,没有headers等参数,也就是没法进行伪装

re

分析网页源码:

<div class="post-content">
        <p><img src="http://duanziwang.com/usr/uploads/2019/02/3334500855.jpg" alt="产品经理视角 vs 用户视角" title="产品经理视角 vs 用户视角"></p>    </div>

案例, 下载段子网搞笑图片页的图片:

所有图片都在post-content对应的div中

import re
import os
import urllib

url = 'http://duanziwang.com/category/搞笑图/'
page_text = requests.get(url,headers=headers).text #页面源码数据

#新建一个文件夹
dirName = 'imgs'
if not os.path.exists(dirName):
    os.mkdir(dirName)

#数据解析:每一张图片的地址
pattern = '<div class="post-content">.*?<img src="(.*?)" alt=.*?</div>'
img_src_list = re.findall(pattern,page_text,re.S) #因为存在换行,爬虫中使用findall函数必须要使用re.S

for src in img_src_list:
    imgName = src.split('/')[-1]
    imgPath = dirName+'/'+imgName
    urllib.request.urlretrieve(url=src,filename=imgPath)
    print(imgName,'下载成功!!!')

注意,这里用到了re.findall中的flag参数:

flag主要有以下取值:

  1. re.I 忽略大小写
  2. re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
  3. re.M 多行模式
  4. re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
  5. re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
  6. re.X 为了增加可读性,忽略空格和 # 后面的注释

bs4

- 环境的安装:
    - pip install bs4
    - pip install lxml

- 解析原理
    - 实例化一个BeautifulSoup的一个对象,把即将被解析的页面源码内容加载到该对象中
    - 调用BeautifulSoup对象中相关的方法和属性进行标签定位和本文数据的提取

- BeautifulSoup对象的实例化的方式:
    - BeautifulSoup(fp,'lxml'):将本地的文件内容加载到该对象中进行数据解析
    - BeautifulSoup(page_text,'lxml'):将互联网上请求到的数据加载到该对象中进行数据解析

### 相关解析操作
- 标签定位:返回值一定是定位到的标签
    - soup.tagName:定位到第一个出现的tagName标签.返回的是单数
    - 属性定位:soup.find('tagName',attrName='value'),返回的是单数
    - find_all('tagName',attrName='value')返回的是复数(列表)
    - 选择器定位:select('选择器'),返回的也是一个列表
        - 层级选择器:
            - 大于号:表示一个层级
            - 空格:标识多个层级
- 取文本
    - string:只可以将标签中直系的文本取出
    - text:可以将标签中所有的内容取出
- 取属性
    - tag['attrName']

案例:爬取名著:《红楼梦》

http://www.shicimingju.com/book/hongloumeng.html

首先,分析下网页:章节名(目录)都在一个网页中, 有个div,book-mulu,然后ul,li里面即是章节链接 章节名。

<div class="book-mulu">
            <ul>
                <li><a href="/book/hongloumeng/1.html">第 一 回 甄士隐梦幻识通灵 贾雨村风尘怀闺秀</a></li>
import re
import os

import requests
from bs4 import BeautifulSoup


headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
}
base_url = 'http://www.shicimingju.com'
category_url = 'http://www.shicimingju.com/book/hongloumeng.html'
category_html = requests.get(url=category_url, headers=headers).text
soup = BeautifulSoup(category_html, 'lxml')
a_list = soup.select('.book-mulu li a')

dir_name = '红楼梦'
if not os.path.exists(dir_name):
    os.mkdir(dir_name)

for a in a_list:
    detail_url = base_url + a['href'] # 拼接详情页url
    name = a.text # 章节名
    file_path = os.path.join(dir_name, name+'.txt') # 拼接文件名
    detail_html = requests.get(detail_url, headers=headers).text # 获取详情页数据
    detail_soup = BeautifulSoup(detail_html, 'lxml')

    article = detail_soup.find('div', class_='card bookmark-list').text # 获取详情页文字内容


    with open(file_path, 'w',encoding='utf-8') as fp:

        fp.write(article)

 

 

上一篇:Fiddler使用

下一篇:Xpath 去掉文本中的空格换行符