Python爬虫教程

Python爬虫教程一

什么叫爬虫?

——通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程。

爬虫的价值?

爬虫合法性

——法律不被禁止

——具有违法风险

——善意爬虫 恶意爬虫

恶意爬虫:

  1. 爬虫干扰了被访问网站的正常运营;
  2. 爬虫抓取了受到法律保护的特定类型的数据或信息;

避免编写爬虫时进入局子:

  1. 时常优化自己的程序,避免干扰被访问网站的正常运行;
  2. 使用传播爬取到的数据时,审查抓取到的内容,若有涉及用户隐私或商业机密等内容,需及时停止爬取和传播;

爬虫教程的分类

  • 通用爬虫

    抓取系统的重要组成部分。(搜索引擎)抓取的是互联网中一整张的页面数据。

  • 聚焦爬虫

    是建立在通用爬虫的基础之上。

    特点是只抓取页面中特定的局部内容,筛选整张页面数据中的有用数据。

  • 增量式爬虫(重点)

    监测网站中数据更新的情况。

    只会抓取网站中最新更新出来的数据。

爬虫中的矛与盾

反爬机制

  • 门户网站通过制定相应的策略技术手段,防止爬虫程序进行网站数据的爬取。

反反爬策略

  • 爬虫程序通过制定相关的策略或者技术手段用来破解门户网站中具备的反爬机制,从而获取门户网站中相关的数据。

反爬虫机制

http协议

  • 概念:服务器和客户端之间进行数据交互的一种形式。
  • 常用请求头信息
    • user-agent :请求载体的身份标识
    • Connection: 请求完毕后,是断开连接还是保持连接
  • 常用响应头信息
    • Content-Type: 服务器响应会客户端的数据类型

https协议

  • 表示安全的http(超文本传输)协议,服务器与客户端进行交互的数据进行加密。

  • 加密方式

    • 对称秘钥加密

      客户端制定某种加密规定,对传给服务器的数据进行加密,然后发送加密后的数据和秘钥发给服务器,服务器再用秘钥对加密数据进行解析。

      缺点:容易在传输过程中被拦截窃取。

    • 非对称秘钥加密

      使用两把锁,一把“私有秘钥”,一把“公开秘钥”。

      1. 服务器A创建秘钥对
      2. 发送公钥给客户端B
      3. B客户端按照公钥进行加密
      4. 把加密的消息发送给A
      5. A使用私钥对消息进行解密

      缺点:

      • 效率低
      • 公钥被拦截后,被第三方篡改公钥,无法保证客户端拿到的公钥是服务器发送的
    • 证书秘钥加密

      服务器和客户端充分信任一个中间的证书认证机构。

      1. 服务器的开发者携带公开密钥,向数字证书认证机构提出公开密钥的申请
      2. 数字证书认证机构认清申请者的身份后,审核通过,对申请者的公开密钥进行数字签名,然后分配这个已签名的公开密钥,将密钥放在证书里,绑定在一起。
      3. 服务器将这份数字证书发送给客户端,因为客户端也认证书机构,通过数字证书中的数字签名来验证公钥的真伪,保证服务器传过来的公钥是真实的。
      4. 确认无误,客户端使用公钥对报文进行加密后发送,服务器收到以后再使用自己的私钥进行解密。


Python爬虫教程二

requests模块

  • urllib模块
  • requests模块

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

——作用:用来模拟浏览器发请求。

——使用方法:(requests模块的编码流程)

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

环境安装:

  • pip install requests

实战编码:

  • 需求:爬取搜狗首页数据

  • coding

    # -*- coding:utf-8 -*-
    # 需求:爬取搜狗首页的页面数据
    import requests
    if __name__=="__main__":
        #step_1:指定URL
        url='https://www.sogou.com/'
        #step_2:发起请求
        #get方法返回一个响应对象
        response=requests.get(url=url)
        #setp_3:获取响应数据,text返回的是字符串形式的响应数据,对应的是网页页面的源代码,
        page_text=response.text
        #在Terminal打印获取的响应数据
        print(page_text)
        #step_4:持久存储
        #sogou.html 会丢失页面的样式,但是不重要,有数据就行
        with open('./sogou.html','w',encoding='utf-8') as fp:
            fp.write(page_text)
        print('爬取数据结束!!!')

实战案例

——需求

爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)

  • UA检测

  • UA伪装

    # -*- coding:utf-8 -*-
    #需求:简易网页采集器
    #
    
    #反爬机制:
    # UA检测:门户网站的服务器会监测对应请求的载体身份标识,若发现载体为浏览器,则是正常用户发起的请求
    #但是若发现不是浏览器,则该请求为不正常的请求(爬虫),服务器很可能会拒绝该次请求
    
    # UA伪装:让爬虫对应的请求载体身份标识伪装成某一款浏览器
    
    #UA :User-Agent() (请求载体的身份标识,如浏览器)
    import requests
    if __name__=="__main__":
        #UA伪装:将对应的User-Agent封装到字典中
        header={
            'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0'
        }
        url='https://www.sogou.com/web'
        #处理url携带的参数:封装到字典中
        kw=input('enter a word :')#此时词条变成动态的了
        param={
            'query':kw
        }
        #发起请求
        #此时请求对应的url具有动态参数
        response=requests.get(url=url,params=param,headers=header)
        page_text=response.text
        filename=kw+'.html'
        with open(filename,'w',encoding='utf-8') as fp:
            fp.write(page_text)
        print(filename," 保存成功!!!")

破解百度翻译

  • post请求(携带了参数)
  • 响应数据是一组json数据
# -*- coding:utf-8 -*-
#需求:破解百度翻译
#百度翻译具有局部刷新的特性,文本框中录入数据之后会自动刷新,ajax动态加载

#网页检查-network-右侧选中XHR类型请求-此时左侧显示的就是ajax动态加载的数据

#百度翻译ajax动态加载的内容就是我们需要的数据(翻译结果)


import requests
import json
if __name__=="__main__":
    #指定URL,网页检查-消息头-POST查看
    post_url='https://fanyi.baidu.com/sug'
    #post请求参数的处理,设置为动态参数
    word=input('enter what you need translate : ')
    data={
        'kw':word
    }
    #进行UA伪装
    header={
        'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0'
    }
    

    #请求发送
    response=requests.post(post_url,data=data,headers=header)
    #获取响应数据
    #json返回的方法是一个字典对象obj,如果确认服务器的响应是json类型,才能使用json()方法
    # 类型查看可以在:网页检查-消息头-响应头-Content-Type: application/json
    dic_obj=response.json()
    #print(dic_obj)

    #持久化存储
    filename=word+'.json'
    fp=open(filename,'w',encoding='utf-8')
    json.dump(dic_obj,fp=fp,ensure_ascii=False)
    print('OVER !!')

爬取豆瓣电影分类排行榜 https://movie.douban.com/中电影详情数据

# -*- coding:utf-8 -*-
#需求:爬取豆瓣电影分类排行榜 https://movie.douban.com/中电影详情数据
#在排行榜页面往下滑动,网页链接不改变,当滑到底时继续滑动会刷新出新的数据,用的也是ajax动态加载
#网页检查-network-右侧选中XHR类型请求-此时左侧显示的就是ajax动态加载的数据

import requests
import json
if __name__=="__main__":
    #指定url
    url = 'https://movie.douban.com/j/chart/top_list'
    param={
        'type':'5',
        'interval_id': '100:90',
        'action':'',
        'start':'0',#从服务器数据库中第n部电影开始
        'limit':'20',#取20个
    }
    #UA伪装:将对应的User-Agent封装到字典中
    header={
        'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0'
    }

    #发起请求
    response=requests.get(url=url,params=param,headers=header)
    #服务器的响应是json类型,使用json()方法

    list_data=response.json()

    fp=open('./douban.json','w',encoding='utf-8')
    json.dump(list_data,fp=fp,ensure_ascii=False)
    print('OVER !!')

爬取肯德基餐厅查询 http://www.kfc.com.cn/kfccda/index.aspx中指定地点的餐厅数

爬取国家药品监管总局中基于中华人民共和国化妆品生产许可证相关数据

  • 请求的一个页面中有可能包含动态加载的数据(可能是ajax动态加载),不能直接由页面的url链接请求得到
  • ajax请求得到的响应json格式的数据可复制到 json格式化校验网站查看
  • 想要得到每组数据对应的详情url ,可以在json响应中找到其对应的ID,拼接用来查询详情的域名结合,便可得到详情页的URL
  • 详情页的企业数据也是动态加载出来的
    • 观察后发现:
      • 所有的post请求的URL都是一样的,只有参数ID值是不同的
      • 如果我们可以批量获取多家企业的ID后,就可以将ID与URL形成一个完整的详情页数据的ajax请求URL。


python爬虫教程三

数据解析

  • 聚焦爬虫:爬取页面中指定的页面内容。
    • 编码流程
      1. 指定URL
      2. 发起请求
      3. 获取响应数据
      4. 数据解析
      5. 持久化存储
  • 数据解析分类:

    • 正则
    • bs4
    • xpath (***)
  • 数据解析原理概述

    解析的局部的文本内容都会在标签之间或者标签对应的属性中进行存储。

    1. 指定标签的定位。

    2. 标签或者标签对应的属性中存储的数据值进行提取(解析)。

正则表达式

image-20211113184440331

  • 正则练习

image-20211113184547349


需求:爬取糗事百科中糗图板块下的所有糗图图片

# -*- coding:utf-8 -*-

#需求:爬取糗事百科中糗图板块下的一张糗图图片
import requests
if __name__=="__main__":
    headers = {
        'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0'
    }
    url = 'https://pic.qiushibaike.com/system/pictures/12486/124869891/medium/HH4TOMZKZ1XETGYB.jpg'
    #content 返回的是二进制形式的图片数据
    #text (字符串)   content (二进制)  json() (对象)
    imgdata=requests.get(url=url).content

    with open('./qiutu.jpg','wb') as fp:
        fp.write(imgdata)
# -*- coding:utf-8 -*-

#需求:爬取糗事百科中糗图板块下的所有糗图图片
import requests
import re
import os
if __name__=="__main__":
    #创建一个文件夹用来保存所有图片
    if not os.path.exists('./qiutuLibs'):
        os.makedirs('./qiutuLibs')

    headers = {
        'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0'
    }
    url = 'https://www.qiushibaike.com/imgrank'

    #使用通用爬虫对url对应的一整张页面进行爬取
    page_text=requests.get(url=url,headers=headers).text
    #使用聚焦爬虫将页面中所有的图进行提取
    #在网页代码中找到图片对应的代码部分
    # <div class="thumb">

    # <a href="/article/124823437" target="_blank">
    # <img src="//pic.qiushibaike.com/system/pictures/12482/124823437/medium/E4R7L3PXE17UVETV.jpg" alt="糗事#124823437" class="illustration" width="100%" height="auto">
    # </a>
    # </div>

    #提取上面代码中的 URL : //pic.qiushibaike.com/system/pictures/12482/124823437/medium/E4R7L3PXE17UVETV.jpg
    ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
    #如果正则作用到正则解析,使用的一定是re.S
    img_src_list=re.findall(ex,page_text,re.S)
    #print(img_src_list)
    for src in img_src_list:
        #拼接出一个完整的图片地址
        src = 'https:'+ src
        #请求到了图片的二进制数据
        img_data=requests.get(url=src,headers=headers).content
        #生成图片名称
        img_name=src.split('/')[-1]
        imgPath='./qiutuLibs/'+img_name
        with open(imgPath,'wb') as fp:
            fp.write(img_data)
            print(img_name," 图片下载成功!!\n")
  • 爬取多个页面的图片
# -*- coding:utf-8 -*-

#需求:爬取糗事百科中糗图板块下的所有糗图图片
import requests
import re
import os
if __name__=="__main__":
    #创建一个文件夹用来保存所有图片
    if not os.path.exists('./qiutuLibs'):
        os.makedirs('./qiutuLibs')

    headers = {
        'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0'
    }
    #设置一个通用的URL模板(可切换页面)
    url = 'https://www.qiushibaike.com/imgrank/page/%d/'
    #page_num=2
    for page_num in range(1,3):
        #对应页面的URL
        new_url=format(url%page_num)

        #使用通用爬虫对url对应的一整张页面进行爬取
        page_text=requests.get(url=new_url,headers=headers).text
        #使用聚焦爬虫将页面中所有的图进行提取
        #在网页代码中找到图片对应的代码部分
        # <div class="thumb">

        # <a href="/article/124823437" target="_blank">
        # <img src="//pic.qiushibaike.com/system/pictures/12482/124823437/medium/E4R7L3PXE17UVETV.jpg" alt="糗事#124823437" class="illustration" width="100%" height="auto">
        # </a>
        # </div>

        #提取上面代码中的 URL : //pic.qiushibaike.com/system/pictures/12482/124823437/medium/E4R7L3PXE17UVETV.jpg
        ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
        #如果正则作用到正则解析,使用的一定是re.S
        img_src_list=re.findall(ex,page_text,re.S)
        #print(img_src_list)
        for src in img_src_list:
            #拼接出一个完整的图片地址
            src = 'https:'+ src
            #请求到了图片的二进制数据
            img_data=requests.get(url=src,headers=headers).content
            #生成图片名称
            img_name=src.split('/')[-1]
            imgPath='./qiutuLibs/'+img_name
            with open(imgPath,'wb') as fp:
                fp.write(img_data)
                print(img_name," 图片下载成功!!\n")

bs4 进行数据解析

  • 数据解析的原理

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

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

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

      • form bs4 import BeautifulSoup

      • 对象的实例化:

        1. 将本地的html 文档中的数据加载到该对象中

          import requests
          from bs4 import BeautifulSoup
          if __name__=="__main__":
              #将本地的html文件加载到该对象中
              fp = open('./test.html','r',encoding='utf-8')
              soup=BeautifulSoup(fp,'lxml')
              print(soup)
        2. 将互联网上获取的页面源码加载到该对象中

        #将互联网上获取的页面源码加载到该对象中
        page_text = response.text
        soup=BeautifulSoup(page_text,'lxml')
    • 提供的用于数据解析的方法和属性

      soup.tagName:返回的是html中第一次出现的tagName标签
      print(soup.find('tagName')):等价于print(soup.tagName)
      #属性定位
      soup.find('div',class_='song'):#class后面有下划线,是因为class_是参数名称,不加_就变成关键字了
          
      soup.find_all(‘tagName’):find_all返回,soup页面源码中所有‘tagName’页标签所包含的数据(列表)
      
      soup.select('某种选择器(id,class,标签...选择器)'):select返回的是一个列表
      #层级选择器
      soup.select('.tang > ul > li > a')[0]:定位到<ul><li> 标签 下 <a>标签中的第一个
      或者
      由于<a>不是<ul>的直接子标签,还可写成:
      soup.select('.tang > ul a')[0] :空格表示多个层级,> 表示一个层级
      
      
      
    • 获取标签之间的文本数据

      • soup.a.text/string/get_text()
      • 这几种方法的区别
        • text/get_text() 可以获取一个标签中的所有文本内容
        • string :只可以获取该标签下面直系的文本内容
        • 例如:soup.find('div',class_='song').string
        • soup.find('div',class_='song').text
        • soup.find('div',class_='song').get_text()
    • 获取标签中的属性值

bs4解析案例提取网页中的三国演义https://sanguo.5000yan.com/:

  • 首页页面:

image-20211113183857365

  • 章节详情页:

image-20211113183808817

  • 爬取每一个章节的文字,解析出来后,写入到同一个文件当中
# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
#需求:爬取三国演义小说的章节标题和章节内容https://sanguo.5000yan.com/

if __name__=="__main__":
    #对首页的页面数据进行爬取
    url='https://sanguo.5000yan.com/'
    headers={
        'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0'
    }
    page_text_origin = requests.get(url=url,headers=headers).text
    ##对编码格式为utf-8方式读取
    page_text=page_text_origin.encode('iso-8859-1').decode('utf-8')

    #在首页中解析出章节的标题和详情页的url
    #1.实例化BeautifulSoup对象,需要将页面源码数据加载到该对象中
    soup=BeautifulSoup(page_text,'lxml')
    #解析章节标题
    li_list=soup.select('.sidamingzhu-list-mulu > ul > li')

    fp=open('./sanguo.txt','w',encoding='utf-8')

    for li in li_list:
        title=li.a.string
        detail_url=li.a['href']
        #对详情页发起请求,解析出章节的内容
        detail_page_text_origin=requests.get(url=detail_url,headers=headers).text
        #编码格式设置为utf-8方法
        detail_page_text=detail_page_text_origin.encode('iso-8859-1').decode('utf-8')

        #解析出详情页中相关的章节内容
        detail_soup = BeautifulSoup(detail_page_text,'lxml')
        div_tag=detail_soup.find('div',class_='grap')
        #解析到了章节的内容
        context=div_tag.text
        fp.write(title+':'+context+'\n')
        print(title,'爬取成功!!\n')
       
  

xpath 解析

最常用且最便捷高效的一种解析方式。通用性。解析数据首选。

  • xpath 解析原理:

      1. 实例化一个etree 对象,且需要将被解析的页面源码数据加载到该对象中;
      2. 调用etree 对象中的xpath方法结合xpath表达式实现标签的定位和内容的捕获。
  • 环境的安装

    • pip install lxml
  • 如何实例化一个etree 对象

      1. 将本地的html文档中的源码数据加载到etree 对象中;

        tree=etree.parse(filepath)

      2. 可以将从互联网上获取的源码数据加载到该对象中;

        tree=etree.HTML('page_text')

    • xpath(‘xpath表达式’)

      • /: 表示的是从根节点开始定位,表示的是一个层级;

        r=tree.xpath('/html/body/div')

      • // : 表示的是多个层级;

        r=tree.xpath('/html/body/div')
        #
        r=tree.xpath('/html//div')
        #
        r=tree.xpath('//div')#可以表示从任意位置开始定位
      • 属性定位://div[@class='song'] tag[@attrName="attrValue"]

      • 索引定位:

        #找到class=song属性下标签列表中的第三个<p>标签中的内容,索引从1开始
        r=tree.xpath('//div[@class="song"]/p[3]')
        #返回class=tang中,第三个<li>标签中<a>中所包含的内容文本,是一个列表
        r=tree.xpath('//div[@class="tang"]//li[3]/a/text()')
        #如果只要其中的字符串,改为:
        r=tree.xpath('//div[@class="tang"]//li[3]/a/text()')[0]
      • 取文本:

        • /text()获取标签中直系的文本内容
        • //text()标签中非直系的文本内容(所有的文本内容)
        #返回class=tang中,第三个<li>标签中<a>中所包含的内容文本,是一个列表
        r=tree.xpath('//div[@class="tang"]//li[3]/a/text()')
        #如果只要其中的字符串,改为:
        r=tree.xpath('//div[@class="tang"]//li[3]/a/text()')[0]
        #获取<li><b>文本</b></li>中的内容
        r=etree.xpath('//li[7]//text()')
      • 取属性:

        /@attrName ==> img/@src

        #获取<img>标签中的名为src的属性值
        r=etree.xpath('//div[@class="song"]/img/@src')

xpath 案例:爬取58二手房中房源信息(由于有验证码,所以改为获取三国演义中的章节标题信息)

https://sanguo.5000yan.com/

image-20211113184654873

# -*- coding:utf-8 -*-
import requests
from lxml import etree
# 需求: 爬取解析三国演义中章节信息

if __name__=="__main__":
    #爬取页面源码数据
    url="https://sanguo.5000yan.com/"
    #UA伪装
    headers={
        'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0'
    }
    page_text_origin=requests.get(url=url,headers=headers).text
    page_text=page_text_origin.encode('iso-8859-1').decode('utf-8')
    #数据解析
    tree=etree.HTML(page_text)
    #存储的就是li标签的源码
    li_list=tree.xpath('//ul[@class="paiban"]/li')
    #print(li_list)

    fp=open('sanguo_title.txt','w',encoding='utf-8')
    for li in li_list:
        #"."点表示当前标签局部的源码内容,局部解析,列表元素只有一个,所以取[0]
        title=li.xpath('./a/text()')[0]
        print(title)
        fp.write(title+'\n')

xpath 案例:4K图片解析获取

# -*- coding:utf-8 -*-
import requests
from lxml import etree
import os
# 需求: 解析下载图片

if __name__=="__main__":
    #爬取页面源码数据
    url="https://pic.netbian.com/4kmeinv/"
    #UA伪装
    headers={
        'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0'
    }
    page_text_origin=requests.get(url=url,headers=headers)
    #手动设定响应数据的编码格式
    #page_text_origin.encoding='utf-8'#不一定有效
    page_text=page_text_origin.text
    #数据解析
    tree=etree.HTML(page_text)

    li_list=tree.xpath('//ul[@class="clearfix"]/li')
    #print(li_list)

    if not os.path.exists('./piclibs'):
        os.mkdir('./piclibs')

    for li in li_list:
        #"."点表示当前标签局部的源码内容,局部解析;列表元素只有一个,所以取[0]
        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,'下载成功!!')

xpath 案例:解析出全国所有城市的名称

# -*- coding:utf-8 -*-
import requests
from lxml import etree
import os
# 需求:解析出所有城市的名称https://www.aqistudy.cn/historydata/

if __name__=="__main__":
    #爬取页面源码数据
    url="https://www.aqistudy.cn/historydata/"
    #UA伪装
    headers={
        'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0'
    }
    page_text_origin=requests.get(url=url,headers=headers).text

    tree=etree.HTML(page_text_origin)
    # host_li_list=tree.xpath('//div[@class="bottom"]/ul/li')
    # #print(host_li_list)
    # all_city_names=[]
    # #解析热门城市的名称
    # for li in host_li_list:
    #     host_city_name=li.xpath('./a/text()')[0]
    #     #print(host_city_name)
    #     all_city_names.append(host_city_name)


    # #解析全部城市的名称
    # all_city_list=tree.xpath('//div[@class="bottom"]/ul/div[2]/li')
    # for li in all_city_list:
    #     city_name=li.xpath('./a/text()')[0]
    #     all_city_names.append(city_name)

    # print(all_city_names,'\n',len(all_city_names))



    #解析到热门城市和所有城市对应的a标签
    #热门城市对应的标签层级关系://div[@class="bottom"]/ul/li/a
    #全部城市对应标签层级关系: //div[@class="bottom"]/ul/div[2]/li/a
    #热门+全部城市一次性解析到列表,综合上面两个步骤
    a_list=tree.xpath('//div[@class="bottom"]/ul/li | //div[@class="bottom"]/ul/div[2]/li')
    citys_name=[]
    for a in a_list:python
        city_name=a.xpath('./a/text()')[0]
        citys_name.append(city_name)

    print(citys_name,'\n',len(citys_name))

作业:爬取站长素材中的简历模板



python爬虫教程四

验证码识别

  • 反爬机制:验证码。

  • 识别验证码图片中的数据用于模拟登录操作。

  • 识别验证吗的操作:

    • 人工肉眼识别(效率低)
    • 第三方自动识别(推荐使用)
      • 云打码(没了)
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2024 lk
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信