并不全面

request 模块

  • urllib 模块
  • request 模块

request 模块:python 中原生的一款基于网络请求的模块,功能非常强大,简单便捷,效率极高

使用流程

  • 指定 url
  • 发起请求
  • 获取响应数据
  • 持久化存储

以上也是爬虫的四步法则

环境安装:

pip install requests

编写

  • 爬取搜狗页面的页面数据
import requests
if __name__ == "__main__":
  #指定 url
  url = 'https://www.sogou.com/'
  #发起请求
  #get 返回一个响应对象
  response = requests.get(url=url)
  #获取响应数据 text 返回的是字符串形式的响应数据
  page_text = response.text
  print(page_text)
  #持久化存储
  with open('./sogou.html','w',encoding='utf-8') as fp:
      fp.write(page_text)
  print('爬取结束!')

tips

UA 检测:门户网站的服务器会检测对应请求载体的标识,若检测到请求的载体身份标识是某一浏览器,说明该请求是正常请求【不是基于浏览器的大都是爬虫】
UA 伪装:让爬虫对应的请求载体身份标识伪装成某一款浏览器

编写

  • 简易的网页采集器
#UA 检测 (user-agent): 门户网站的服务器会检测对应请求载体的标识,若检测到请求的载体身份标识是某一浏览器,说明该请求是正常请求【不是基于浏览器的大都是爬虫】
#UA 伪装:让爬虫对应的请求载体身份标识伪装成某一款浏览器
import requests
from requests.models import Response
if __name__ == "__main__":
   #UA 伪装:将对应的 user-agent 封装到一个字典中
   headers = {
       'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0'
   }
   url = 'https://www.baidu.com/s'
   #处理 url 携带参数:封装到字典
   Dic = input('plz enter your word:')
   param = {
       'wd':Dic
   }
   #发起请求
   response = requests.get(url=url,params=param,headers=headers)
   #获得响应数据
   page_text = response.text
   fileName = Dic+'.html'
   with open(fileName,'w',encoding='utf-8') as fp:
       fp.write(page_text)
   print(fileName,'保存成功!')
  • 动态加载数据
  • 首页中对应的企业信息数据是通过 ajax 动态请求到的,详情页的详情数据也是动态加载出来的
  • 观察后发现:
    所有的 post 请求的 url 都是一样的,只有参数 id 的值不同
    我们可以批量获取多家企业的 id,可以将 id 和 url 形成一个完整的详情页对应详情数据的 ajax 请求的 url

编写

  • 豆瓣电影排行榜信息
import requests
import json
if __name__ == "__main__":
   url = 'https://movie.douban.com/j/chart/top_list'
   param = {
       'type': '6',
       'interval_id': '100:90',
       'action':'',
       'start': '0',
       'limit': '20',
   }
   headers = {
       'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0'
   }
   response = requests.get(url=url,params=param,headers=headers)
   list_data = response.json()
   fp = open('./douban.json','w',encoding='utf-8')
   json.dump(list_data,fp=fp,ensure_ascii=False)
   print('生成!!')

数据解析

数据解析原理概述

  • 解析的局部的文本内容都会在标签之间或者标签对应的属性中进行存储
  • 1. 进行指定标签的定位
  • 2. 标签或者标签对应的属性中存储的数据进行提取(解析)

使用流程

  • 指定 url

  • 发起请求

  • 获取响应数据

  • 数据解析

  • 持久化存储

    • 聚焦爬虫
    • 爬取页面中指定的页面内容

编写

爬取页面图片

import requests
  if __name__ == "__main__":
    #UA 伪装:将对应的 user-agent 封装到一个字典中
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0'
    }
    url = 'https://blog.lxscloud.top/static/post/esp32_cam/360%E6%88%AA%E5%9B%BE16810304334270.jpg'
    img_data = requests.get(url=url).content
    #content 返回的是二进制形式的图片数据
    #text (字符串) content (二进制) json (对象)
    with open('./my.jpg','wb') as fp:  #wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
        fp.write(img_data)

正则

参考此篇学习正则

正则解析:

<div class="thumb">
<a href="/article/125091174" target="_blank">
<img src="//pic.qiushibaike.com/system/pictures/12509/125091174/medium/Z9FEKWUBTD8D11QV.jpg" alt="糗事#125091174" class="illustration" width="100%" height="auto">
</a>
</div>
ex = '<div class="thumb">.*?'<img src="(.*?)" alt.*?</div>div>'

编写

用正则爬取指定页面所有图片

import requests
import re
import os
if __name__ == "__main__":
    #创建一个文件夹,保存所有的图片
    if not os.path.exists('./qiutuLibs'):
        os.mkdir('./qiutuLibs')
    url = 'https://www.qiushibaike.com/imgrank/page/%d/'  #处理分页
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0'
    }
    for pageNum in range(1,3):
        #对应页码的 url
        new_url = format(url%pageNum)
        page_text = requests.get(url=new_url,headers=headers).text #使用通用爬虫对 url 对应的一张页面进行爬取
        ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>' #聚焦爬虫将页面中所有图进行提取
        img_src_list = re.findall(ex,page_text,re.S) #re.S 单行匹配正则,re.M 多行匹配正则
        for src in img_src_list:
           src = 'https:' + src #拼接图片完整路径
           img_data = requests.get(url=src,headers=headers).content #返回的是二进制形式的图片数据
           img_name = src.split('/')[-1] #生成图片名称
           img_path = './qiutuLibs/' + img_name #生成存储路径
           #持久化存储
           with open(img_path,'wb') as fp:
               fp.write(img_data)
               print(img_name,'下载成功!!')

bs4

bs4 解析

  • 数据解析的原理:

    • 1. 标签定位
    • 2. 提取标签、标签属性中存储的数据值
  • bs4 数据解析的原理:

    • 1. 实例化一个 BeautifulSoup 对象,并且将页面源码数据加载到该对象中
    • 2. 通过调用 BeautifulSoup 对象中相关的属性或者方法进行标签定位和数据提取
  • 环境安装:

    • pip install bs4
    • pip install lxml
  • 如何实例化 BeautifulSoup 对象:

    • from bs4 import BeautifulSoup
    • 对象的实例化:
      • 1. 将本地的 html 文档中的数据加载到该对象
        fp = open ('./test.html','r',encoding='utf-8')
        soup = BeautifulSoup(fp,'lxml')
      • 2. 将互联网上网页源码的数据加载到该对象
        page_text = response.text
        soup = BeautifulSoup(page_text,'lxml')
    • 提供的用于数据解析的方法和属性:
      • soup.tagName: 返回的是文档中第一次出现的 tagName 对应的标签
      • soup.find():
        • find ('tagName'): 等同于 soup.div
        • 属性定位:
          • soup.find('div',class_/id/attr='song')
        • soup.find_all ('tagName'): 返回符合要求的所有标签 (列表)
    • select:
      • select (' 某种选择器 (id,class, 标签... 选择器)'), 返回的是一个列表。
      • 层级选择器:
        • soup.select ('.tang> ul > li > a'): > 表示的是一个层级
        • soup.select ('.tang> ul a'): 空格表示的多个层级
      • 获取标签之间的文本数据:
        • soup.a.text/string/get_text()
        • text/get_text (): 可以获取某一个标签中的所有文本内容
        • string: 只可以获取该标签下直系的文本内容
      • 获取标签中属性值:
        • soup.a['href']

编写

#爬取三国演义的所有章节及其内容
from bs4 import BeautifulSoup
import lxml
import requests
if __name__ == "__main__":
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0'
    }
    url = 'https://www.shicimingju.com/book/sanguoyanyi.html'
    page_text = requests.get(url=url,headers=headers).text
    #在首页中解析出章节的标题和详情页的 url
    #1. 实例化 BeautifulSoup 对象,需要将页面源码数据加载到该对象
    soup = BeautifulSoup(page_text,'lxml')
    #2. 解析出详情页的标题和 url
    li_lixt = soup.select('.book-mulu > ul > li')
    fp = open('./sanguo.txt','w',encoding='utf-8')
    for li in li_lixt:
        title = li.a.string
        d_url = 'https://www.shicimingju.com'+li.a['href']
        #对详情页发起请求,解析出章节内容
        d_text = requests.get(url=d_url,headers=headers).text
        d_soup = BeautifulSoup(d_text,'lxml')
        div_tag = d_soup.find('div',class_='chapter_content')
        #解析到章节内容
        content = div_tag.text
        fp.write(title+':'+content+'\n')
        print(title,'爬取成功')

xpath

  • xpath 解析原理:
    • 1. 实例化一个 etree 的对象,且需要将被解析的页面源码数据加载到该对象中。
      • 2. 调用 etree 对象中的 xpath 方法结合着 xpath 表达式实现标签的定位和内容的捕获。
  • 环境的安装:
    • pip install lxml
  • 如何实例化一个 etree 对象: from lxml import etree
    • 1. 将本地的 html 文档中的源码数据加载到 etree 对象:
      etree.parse(filePath)
    • 2. 可以将从互联网上获取的源码数据加载到该对象中
      etree.HTML ('page_text')
    • xpath ('xpath 表达式 ')
      • /:表示从根节点开始定位,一个 / 表示一个层级 // 表示多个层级
      • 属性定位: //div [@class='song'] -------->tag [@attrName='attrValue']
      • 索引定位: //div [@class='song']/p [3] 从 1 开始索引
      • 取文本:
        • /text () 获取的是标签中直系的文本内容
        • //text () 获取标签中非直系的文本内容(所有的文本内容)
      • 取属性:
        /@attrName ====> img/src

编写

  • 58 二手房
from socket import herror
import requests
from lxml import etree
if __name__ == "__main__":
    url = 'https://bj.58.com/ershoufang/'
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0'
    }
    page_text = requests.get(url=url,headers=headers).text
    tree = etree.HTML(page_text)
    li_list = tree.xpath('//section[@class="list"]/div')
    fp = open('58.txt','w',encoding='utf-8')
    for li in li_list:
        title = li.xpath('./a/div[2]/div[1]/div[1]/h3/text()')[0]
        print(title)
        fp.write(title+'\n')
  • 爬图片
import requests
from lxml import etree
import os
if __name__ == "__main__":
    url = 'https://pic.netbian.com/4kdongman/'
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0'
    }
    page_text = requests.get(url=url,headers=headers).text
    # 数据解析:src 的属性值 alt 属性值
    tree = etree.HTML(page_text)
    li_list = tree.xpath('//div[@class="slist"]/ul/li')
    if not os.path.exists('./picLibs'):
        os.mkdir('./picLibs')
    for li in li_list:
       img_src = 'https://pic.netbian.com'+li.xpath('./a/img/@src')[0]
       img_name = li.xpath('./a/img/@alt')[0]+'.jpg'
       img_name = img_name.encode('iso-8859-1').decode('gbk')
      # print(img_name,img_src)
       img_data =  requests.get(url=img_src,headers=headers).content
       img_path = 'picLibs/'+img_name
       with open(img_path,'wb') as fp:
           fp.write(img_data)
           print(img_name,'Download succeed!')

自己写的爬简历

import requests
from lxml import etree
import os
if __name__ == "__main__":
    url = 'https://sc.chinaz.com/jianli/free_%d.html'
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0'
    }
    if not os.path.exists('./pics'):
          os.mkdir('./pics')
for page in range(1,21):
       if page == 1:
          new_url = 'http://sc.chinaz.com/jianli/free.html'
       else:
          new_url = format(url%page)
       page_text = requests.get(url=new_url,headers=headers).text
       tree = etree.HTML(page_text)
       li_list = tree.xpath('//*[@id="container"]/div')
       #print(li_list)
       for li in li_list:
          img_src ='http:'+li.xpath('./a/@href')[0]
          # print(img_src)
          img_name = li.xpath('./a/img/@alt')[0]+'.rar'
          img_name = img_name.encode('iso-8859-1').decode('utf-8')
          #print(img_name)
          img_data = requests.get(url=img_src,headers=headers).text
          #print(img_data)
          tree = etree.HTML(img_data) # very essential!
          download_src = tree.xpath('//div[@id="down"]/div[2]//li[6]/a/@href')[0]
         # print(download_src)
          img_data = requests.get(url=download_src,headers=headers).content
          
          img_path = 'pics/'+img_name
          with open(img_path,'wb') as fp:
              fp.write(img_data)
              print(img_name,'Download succeed!')

验证码识别

反爬机制:验证码,识别验证码图片中的数据,用于模拟登录操作

识别验证码的操作:
- 人工肉眼识别
- 第三方自动识别
- 云打码: http://www.yundama.com/demo.html
云打码使用流程:
- 注册:普通和开发者用户
- 登录:
- 普通用户的登录:查询该用户是否还有剩余的部分
- 开发者用户的登录:
- 创建一个软件:我的软件 -> 添加新软件 -> 录入软件名称 -> 提交 (软件 id 和密钥)
- 下载实例代码:开发文档 -> 点此下载:云打码接口 DLL -> PythonHTTP 实例下载

模拟登录:
- 爬取基于某些用户的用户信息

需求:对人人网进行模拟登录
- 点击登录按钮后会发起一个 post 请求
- post 请求中会携带登录之前录入的相关的登录信息 (用户名、密码、验证码)

谢谢观看

更新于

请我喝[茶]~( ̄▽ ̄)~*

1sme 微信支付

微信支付