Python爬虫学习

通用爬虫模块学习

1、爬虫的概念

  • 爬虫是模拟浏览器发送请求,获取相应
  • 爬虫的流程
    • URL—>发送请求,获取相应—>提取数据—>保存本地
    • 发送请求,获取相应—提取URL
发送请求
url list
相应内容
提取url
提取数据
模块D
  • 爬虫要根据当前url地址对应的响应为准,当前url地址的elements的内容和url的响应network不一样
  • 页面上的数据在哪里
    • 当前url地址对应的响应中
    • 其他的url地址对应响应中
      • 比如ajax请求中
    • js生成
      • 部分数据在响应中
      • 全部通过js生成

2、requests库学习

  • 为什么学习requests,而不是urllib
    1.requests的底层就是urllib
    2.requests在Python2和Python3中通用,方法完全一样
    3.requests简单易用
    4.requests能够自动帮助我们解压(gzip压缩的等)网页内容

  • url编码

    • http://www.baidu.com/s?wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2
  • 字符串格式化的另一种方式

    "传{}智播客".format(1)
    
  • 保存页面

    with open('renren1.html','w',encoding='utf-8') as f:    
          f.write(response.content.decode())
    
  • 保存图片

    with open('1.png/jpg','wb') as png:    
          png.write(response.content)
    
  • 字典推导式和列表推导式

    • 字典推导式
       cookies = '......network中的cookie'
      #字典推导式
      cookies = {i.split("=")[0]:i.split("=")[1] for i in cookies.split("; ")}
      
    • 列表推导式
      return [self.url_temp.format(i*50) for i in range(1000)]#主流写法
      
  • requests小技巧

    • requests.utils.dict_from_cookiejar ( 把cookie对象转化为字典)
      print(requests.utils.dict_from_cookiejar(response.cookies))
      
    • url解码:requests.utils.unquote(‘url带%的地址’)
    • 请求SSL证书验证:
      response = requests.get('https://www.12306.cn/mormhweb',verify=False)
      
    • 设置超时参数:
      response = requests.get(url,timeout=10)
      
    • 配合状态码判断请求是非成功
      assert response.status_code==200
      
  • 发送简单的请求

    • 用法
      response = request.get(url)
      
    • response的常用方法:
      1.response.text:打印网页源码(会乱码)
      2.response.content:打印二进制数据
      3.response.content.decode():打印网页(必须带有cookie值)
      4.response.status_code:打印响应码
      5.response.headers:获取响应头
      6.response.request.headers/url/cookies… :获取请求头/请求url/cookies对象。。。
  • 发送post请求

    • 哪些地方会用到发送post请求:
      1. 登录注册
      2. 需要传输大文本内容的时候
      3. 用法
      response = requests.post(url,data=data,headers=headers) (data形式:字典)
  • 使用代理

    • 准备一堆ip地址,组成ip池,随机选择一个ip来访问
    • 如何选择代理ip,让使用次数较少的ip地址有更大可能性被使用
      • {“ip”:ip,“times”:0}
      • [{},{},{},{},{}],对这个ip列表进行排序,按照使用次数times进行排序
      • 选择使用次数较少的从中随机选择一个
    • 为什么要使用代理?
      1.让服务器以为不是同一个客户端请求
      2.防止我们的真实地址被泄露,防止被追究!
    • 用法
      proxies = {
                   "http":"http://12.34.56.79:9527:80",或者
                   "https":"https://12.34.56.79:9527:80",
                   }
      response = requests.get(url,proxies=proxies) (proxie的形式:字典)
            
      
    • 检查ip的可用性
      1.可以使用requests添加超市参数,判断IP质量
      2.在线代理ip质量检测的网站
  • 携带cookie请求

    • cookie和session的区别
      1.cookie数据存放在客户的浏览器上,session数据放在服务器上
      2.cookie不是很安全,别人可以分析放在本地的cookie进行cookie欺骗
      3.session会在一定时间内保存在服务器上,当访问增多,会比较占用服务器性能
      4.单个cookie数据不能超过4k,很多浏览器限制一个站点最多保存20个cookie
    • 携带一堆cook进行请求,组成cookie池。。。如上
    • 携带cookie、session的好处:能够请求到登录之后的界面
    • 携带cookie、session的弊端:一套cookie和session往往和一定用户对应,请求太快,次数太多,容易被识别为爬虫
    • 为了获取登录后的页面,必须发送带有cookie的请求
    • 使用request提供的session类来请求登录之后的网站思路
      1.实例化session
      2.先试用session发送请求,登录网站,把cookie保存在session中
      3.再使用session请求登陆之后才能访问的网站,session能够自动的携带登陆成功时保存在其中的 cookie,进行访问
    • 模拟登录获取登录后的页面三种方法
      • 第一种:实例化session发送post登录,再使用session获取登录后的页面
        #使用session发送post请求,cookie保存在其中
        session.post(post_url,data=post_data,headers=headers)
        #再使用session进行请求登录后才能访问的地址
        r = session.get('http://www.renren.com/976812720/newsfeed/photo',headers=headers)
        
      • 第二种:在headers添加cookie键,值为cookie字符串
         headers = {
                    'User-Agent':'...',
                    'Cookie':'...network中的cookie值'
                    }
        
        • 哪些情况可以这样?
          1.cookie过期时间很长的网站
          2.在cookie过期之前能够拿到所有数据,比较麻烦
          3.配合其他程序一起使用,其他程序专门获取cookie,当前程序专门请求页面
      • 第三种:在请求方法中添加cookies参数,接受字典型cookie。
        cookies = '......network中的cookie'
        #字典推导式
        cookies = {i.split("=")[0]:i.split("=")[1] for i in cookies.split("; ")}
        r=session.get('http://www.renren.com/976812720/newsfeed/photo',headers=headers,cookies=cookies)
        

3、Chrome分析post和json

  • 寻找登录post的地址
    • 第一种:在from表单中寻找action对应的url地址
      • post的数据是input标签中的name的值作为键,真正的用户密码作为值的字典,post的url地址就是action对应的地址
    • 第二种:抓包,寻找登录的url地址
      1.勾选network中的perserver log按钮,防止页面跳转找不到url地址
      2.寻找post数据,确定参数(多登录几次)
      • 参数不会变,直接用,比如密码不是动态加密的时候
      • 参数会变
        • 在当前响应中
        • 通过js生成
    • 定位想要的js
      • 选择会触发的js时间的按钮,点击ELememns中的event listener,找到js位置
      • 通过Chrome中的search 来搜索url中关键字
      • 添加断点的方式来查看js操作,通过Python来进行同样操作

4、数据分类

  • 非结构化的数据:html等
    • 处理方法:正则表达式、xpath
  • 结构化数据:json,xml等
    • 处理方法:转化为python数据类型

5、json数据处理

  • json注意点
    • json是一种轻量级的数据交换式,适用于数据交互情景
    • 哪里能找到json的url
      1.使用Chrome切换到手机页面
      2.抓包手机app的软件
    • json中字符串都是用双引号引起来的
    • 如果不是双引号
      • eval:能实现简单的字符串和简单的Python类型的转化
      • replace:把单引号替换为双引号
    • 往一个文件中写入多个json串,不再是一个json串,不能直接读取(写保存在本地找对应行的问题)
      • 一行写一个json串,按行来读取
  • json字符串<—>Python数据类型
    • json.loads把json转换为Python类型
      ret1 = json.loads(html_str)
      或者
      with open('douban.json','r',encoding='utf-8') as f:
         ret2 = f.read() (需要先读一下)
         ret3 = json.loads(ret2)
         print(ret3)
      
    • json.dumps能够把就Python类型转化为json
      with open('douban.json','w',encoding='utf-8') as f:
          f.write(json.dumps(ret1,ensure_ascii=False,indent=2))  
      (ensure_ascii=False在json中文显示中文,indent=2缩进两格,显示好看)
      
  • 包含json的类文件对象<—>python
    • 类文件对象:具有read()或者write()方法的对象 (f = open(‘a.txt’,‘r’))f就是类文件对象
    • json.load提取类文件对象中的数据
      with open('douban.json','r',encoding='utf-8') as f:
        ret4 = json.load(f) (直接转换)
        print(ret4)
      
    • json.dump能够把Python类型放入类文件对象中
      with open('douban.json','w',encoding='utf-8') as f:
        json.dump(ret,f)
      

6、正则表达式(匹配列表)

  • 定义:用事先定义好特殊字符,组成“规则字符串”,表达对字符串的一种过滤逻辑

  • 用途:较少的数据时使用正则,如一个价格

  • 常用正则表达式的方法:
    re.complie(编译)
    re.match(从头找一个)
    re.search(找一个)
    re.findall(找所有)
    re.sub(替换)
    Python爬虫学习_第1张图片

  • 贪婪(.*):尽可能匹配多的字符

    r = re.findall('<.+>',a,re.S)  (从第一个<匹配到最后一个)
    print(r)  
    
  • 非贪婪(.*?):尽可能少的数据,匹配完一个接着匹配下一个

    r = re.findall('<.+?>',a,re.S)  (从第一个<匹配到第二个,接着匹配下个)
    print(r)  
    
  • re .sub(替换)方法

    a = 'chuan1zhi2 '
    print(re.sub('\d','_',a))
    
  • re.complie(编译)方法

    a = 'chuan1zhi2 '
    p = re.compile('.',re.S) (编译后p可以调用re其他方法节省运行时间,如果有re.S,re.DOALL放这)
    print(p.findall('\n'))
    
  • 原始字符串r的用法:待匹配的字符串中看到什么就在正则表达式中写什么,能忽略\带有转译的影响

    a = re.findall(r'a\\nb','a\\nb')
    print(a)
    r'a\nb' == 'a\\nb'True
    • 在window下操作文件路径
      f = open(r"C:\Users\1.txt","r") (如果没有r需要写\\)
      
  • ()的使用:只匹配括号中的,括号前后定位和起过滤作用

    re.findall(r'a(.*)bc','a\nbc',re.DOTALL)
    输出:['\n']  
    
  • 双引号里有双引号加\

    r"

    .*?

    (.*?)

    " (提取h1=title里面p标签的所有数据)

7、Xpath

  • lxml是一款高性能的Python HTML/XML解析器,我们可以利用Xpath来快速定位特定元素以及获取节点信息。XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。

  • 工具:
    1.Chrome插件 Xpath Helper
    2.开源的Xpath表达式编辑工具:XML Quire(xml格式文件可用)
    3.Firefox插件 Xpath Checker

  • 节点选择语法
    Python爬虫学习_第2张图片Python爬虫学习_第3张图片Python爬虫学习_第4张图片![在这里插入图片描述](https://img-blog.csdnimg.cn/20210604191327579.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3l1YW4yMDE5MDM1MDU1,size_16,color_FFFFFF,t_70#pic_center

  • Xpath学习重点

    • 使用Xpath helper或者是Chrome中的copy Xpath都是从element中提取的数据,但是爬虫获取的是url对应的响应,往往和element不一样
    • 获取文本
      • a/text() 获取a下的文本
      • a//text() 获取a下的所有标签的文本
      • //a[text()=‘下一页 >’] 选择文本为下一页三个字的a标签
    • @符号
      • a@href
      • //ul[@id=‘tetail_list’] (帮助定位)
      • //a/@href 获取a标签中href的url
    • //符号
      • 在Xpath开始的时候表示从当前html中任意位置开始选择
      • li//a :表示li下任何一个a标签
    • xpath的包含关系
      • //div[contains(@class,‘i’)] class包含i的div

8、lxml

  • lxml 可以接收bytes和str的字符串
  • 利用etree.HTML,将字符串转化为Element对象
    html = etree.HTML(text)
  • Element对象具有xpath的方法
    html.xpath(’’)
  • lxml可以自动修正和补全html代码,可能会改错需要查看下
    • etree.tostring(html) 可以查看element对象中所包含的字符串,根据修正后的HTML写Xpath
  • 提取页面数据的思路
    • 先分组,取到一个包含分组标签的列表
      ret3 = html.xpath("//li[@class='item-1']")
      
    • 遍历,取其中每一组数据进行提取,不会造成数据的对应错乱
      for i in ret3:    
         item = {}
         item['title'] = i.xpath("./a/text()")[0] if len(i.xpath("./a/text()")) > 0 else None
         item['href'] = i.xpath("./a/@href")[0] if len(i.xpath("./a/@href")) > 0 else None
         print(item)
      

scrapy框架学习

1、scrapy框架环境搭建

  • 第一步:安装Twisted模块
    (1)打开(https://www.lfd.uci.edu/~gohlke/pythonlibs/),按下快捷键搜 索"twisted"模块下载对应版本
    (2)python3.9就下载“Twisted-20.3.0-cp39-cp39-win_amd64.whl”
    (3)以管理身份运行命令提示符窗口,cd进入“Twisted-20.3.0-cp39-cp39-win_amd64.whl”文件所在位置,然后输入“pip install Twisted-20.3.0-cp39-cp39-win_amd64.whl”
  • 第二步cmd窗口:安装scrapy框架:pip install Scrapy -i https://pypi.douban.com/simple/
  • 第三步cmd窗口:安装pywin32:pip install pywin32 -i https://pypi.douban.com/simple/

2、scrapy框架创建项目

  • 第一步:创建一个文件命名为Scrapy
  • 第二步:创建scrapy框架之前,首先要确保把框架创建在我们刚刚新建的文件夹Scrapy中:
    (1)打开管理员命令行窗口:输入cd 后面跟一个空格 然后把你新建的Scrapy文件路径位置复制进终端里
    (2)输入“scrapy startproject scrapyDemo” 可创建名称“scrapyDemo”的项目
    (3)cd scrpayDemo
    (4)生成一个爬虫scrapy genspider itcast “itcast.cn” ,其中“itcast”是定义的爬虫名称,“itcast.cn”是限制只能在这个网段中爬取不会跑到其他网址
  • 第三步:修改配置:这里我们要改一下settings.py里的内容:
    (1)打开文件,找到代码的第22行,把 ROBOTSTXT_OBEY=True 改为 False,这行代码表示是否遵循爬虫协议,如果是Ture的可能有些内容无法爬取
    (2)将第67到69行代码解注释,并把300改为1,这是优先级设置
  • 第四步:运行爬虫
    使用pycharm时,在底部Terminal窗口中输入“scrapy crawl quotes”,“quotes”为自己定义的爬虫名

3、scrapy框架使用介绍

  • 框架中个文件的作用
    • items.py:定义爬虫程序的数据模型
    • middlewares.py:定义数据模型中的中间件
    • pipelines.py:管道文件,负责对爬虫返回数据的处理
    • settings.py:爬虫程序设置,主要是一些优先级设置,优先级越高,值越小
    • scrapy.cfg:内容为scrapy的基础配置

未更完…

你可能感兴趣的:(python,爬虫)