一、实现数据爬取的流程

 

  1. 指定url
  2. 基于requests模块发起请求
  3. 获取响应对象中的数据
  4. 数据解析
  5. 进行持久化存储

  在持久化存储之前需要进行指定数据解析。因为大多数情况下的需求,我们都会指定去使用聚焦爬虫,也就是爬取页面中指定部分的数据值,而不是整个页面的数据。

 二、常用正则表达式回顾

  单字符:
        . : 除换行以外所有字符
        [] :[aoe] [a-w] 匹配集合中任意一个字符
        \d :数字  [0-9]
        \D : 非数字
        \w :数字、字母、下划线、中文
        \W : 非\w
        \s :所有的空白字符包,括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
        \S : 非空白
数量修饰:
* : 任意多次 >=0 + : 至少1次 >=1 ? : 可有可无 0次或者1次 {m} :固定m次 hello{3,} {m,} :至少m次 {m,n} :m-n次
边界: $ : 以某某结尾
^ : 以某某开头
分组: (ab)
贪婪模式: .
*

非贪婪(惰性)模式: .*? re.I : 忽略大小写 re.M :多行匹配 re.S :单行匹配 re.sub(正则表达式, 替换内容, 字符串)

三、正则表达式基础练习

import re
#提取出python
key="javapythonc++php"
re.findall('python',key)[0]
#####################################################################

#提取出hello world key="<html><h1>hello world<h1></html>" re.findall('<h1>(.*)<h1>',key)[0] #####################################################################

#提取170 string = '我喜欢身高为170的女孩' re.findall('\d+',string) #####################################################################

#提取出http://和https:// key='http://www.baidu.com and https://boob.com' re.findall('https?://',key) #####################################################################

#提取出hello key='lalala<hTml>hello</HtMl>hahah' #输出<hTml>hello</HtMl> re.findall('<[Hh][Tt][mM][lL]>(.*)</[Hh][Tt][mM][lL]>',key) #####################################################################

#提取出hit. key='bobo@hit.edu.com'#想要匹配到hit. re.findall('h.*?\.',key) #####################################################################

#匹配sas和saas key='saas and sas and saaas' re.findall('sa{1,2}s',key) #####################################################################

#匹配出i开头的行 string = '''fall in love with you i love you very much i love she i love her''' re.findall('^.*',string,re.M) #####################################################################

#匹配全部行 string1 = """<div>静夜思 窗前明月光 疑是地上霜 举头望明月 低头思故乡 </div>""" re.findall('.*',string1,re.S)

四、项目实例(糗事百科)

  项目需求:

  1. 爬取糗事百科指定页面的糗图,并将其保存到指定文件夹中

  2. 数据解析方式:re

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import re
import os
if __name__ == "__main__": url = 'https://www.qiushibaike.com/pic/%s/' headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', } #指定起始也结束页码 page_start = int(input('enter start page:')) page_end = int(input('enter end page:')) #创建文件夹 if not os.path.exists('images'): os.mkdir('images')
#循环解析且下载指定页码中的图片数据 for page in range(page_start,page_end+1): print('正在下载第%d页图片'%page) new_url = format(url % page) # 拼接url response = requests.get(url=new_url,headers=headers) #解析response中的图片链接 e = '<div class="thumb">.*?<img src="(.*?)".*?>.*?</div>' pa = re.compile(e,re.S) image_urls = pa.findall(response.text)
#循环下载该页码下所有的图片数据 for image_url in image_urls: image_url = 'https:' + image_url # 拼接详情页url image_name = image_url.split('/')[-1] # 图片名字,字符串分割split image_path = 'images/'+image_name # 路径拼接         

        # 图片保存 content获取的Bytes的字节流 图片&音频&视频都是Bytes类型 image_data
= requests.get(url=image_url,headers=headers).content with open(image_path,'wb') as fp: fp.write(image_data)