一.什么是爬虫

  爬虫的概念:

  1. 通过编写程序,模拟浏览器上网,让其去互联网上爬取数据的过程.

  爬虫的工作流程:

  1. 模拟浏览器发送请求->下载网页代码->只提取有用的数据->存放于数据库或文件中

  

  1.   

  爬虫的分类:

  • 通用爬虫:爬取全部的页面数据.
  • 聚焦爬虫: 抓取页面中局部的页面数据
  • 增量式爬虫:爬取网站中更新出的数据

  反爬机制

  1. 门户网站会通过制定相关的技术手段阻止爬虫程序进行数据的爬取

  反反爬策略:

  • robots.txt协议: 防君子不防小人的协议
  • UA检测 ----->用户表示(通过什么样的代理发起的请求)
  • cookie ------>访问记录
  • 验证码 ------>打码平台
  • 动态加载数 ---->捕获ajax包
  • reference ---->跳转过来的地址

二.requests模块

  1.requests请求过程涉及的协议

  1. #1、请求方式:
  2. 常用的请求方式:
        GET:请求数据
        POST:提交数据
        PUT:更新数据
    DELETE:删除数据
  3.  
  4. postget请求最终都会拼接成这种形式:k1=xxx&k2=yyy&k3=zzz
  5. post请求的参数放在请求体内:
  6. 可用浏览器查看,存放于form data
  7. get请求的参数直接放在url
  8.  
  9. #2、请求url
  10. url全称统一资源定位符,如一个网页文档,一张图片
  11. 一个视频等都可以用url唯一来确定
  12.  
  13. url编码
  14. https://www.baidu.com/s?wd=图片
  15. 图片会被编码(看示例代码)
  16.  
  17. 网页的加载过程是:
  18. 加载一个网页,通常都是先加载document文档,
  19. 在解析document文档的时候,遇到链接,则针对超链接发起下载图片的请求
  1. #3、请求协议格式:
  2.  
  3.   请求首行:
        协议格式:HTTP/HTTPS
        请求方式:GET/POST
        请求主机:
        
      请求头:
      空行:
      请求体:  
  1. #4、请求头
       User-agent:告诉它这是浏览器发过来的请求(请求头中如果没有user-agent客户端配置,服务端可能将你当做一个非法用户)务必加上
       host: 请求主机(服务器)
      cookiescookie用来保存登录信息
       Referer:由哪一个网址跳转过来的,如果直接访问是这个值是空的(用来做防盗链和广告的作用的判断) 一般做爬虫都会加上请求头
       content-type:content-type"urlencoded"/jason--->告诉服务器我提交数据的类型(psot请求才有的)
  2.  
  3. #5、请求体
      如果是get方式,请求体没有内容
      如果是post方式,请求体是format data
      ps
  4.  
  5.   1、登录窗口,文件上传等,信息都会被附加到请求体内
      
    2、登录,输入错误的用户名密码,然后提交,就可以看到post,正确登录后页面通常会跳转,无法捕捉到post

   关于contentype详解

  1. 浏览器------------------>服务器
  2. 1 针对post请求(post请求才有请求体)
  3. 2 向服务器发送post请求有哪些形式:
  4. form表单 (urlencoded编码格式)
  5. user=yuan
  6. pwd=123
  7. Ajaxurlencoded编码格式)
  8. a=1
  9. b=2
  10.  
  11. 请求协议格式字符串
  12. 发送urlencoded编码格式数据
  13. '''
  14. 请求首行
  15. 请求头
  16. content-type:"urlencoded"
  17. 空行
  18. 请求体 # user=yuan&pwd=123 urlencoded编码格式
  19. '''
  20. 发送json数据
  21. '''
  22. 请求首行
  23. 请求头
  24. content-type:"json"
  25. 空行
  26. 请求体 # {"user":"yuan","pwd":123} json编码格式
  27. '''

  2.request爬取数据的流程

requests使用流程:
    -pip install requests
    - 指定url
    - 发起请求
    - 获取响应回来的页面数据
    - 持久化存储

import requests

#爬取搜狗首页的页面数据
#1.指定url
url = 'https://www.sogo.com/'
#2.发起请求:get方法会返回一个响应对象
response = requests.get(url=url)
#3.获取页面数据
page_text = response.text
#4.持久化存储
with open('sogou.html','w',encoding='utf-8') as fp:
  fp.write(page_text)

  3.带User-Agent的请求

  • User-Agent:请求载体的身份标识
  • 反爬机制:浏览器会请求头的UA来检测是用户请求还是机器请求
  • 反反爬策略:获取UA作为request的参数传进去,模拟一个正常的用户(浏览器)

例子:

url = 'https://www.qiushibaike.com/text/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}
#手动设定请求的请求头信息
response = requests.get(url=url,headers=headers)
print(response.text)

  拿UA:

  4.带参数的request

  1. 某些网站会带着我们输入的参数进行请求:
    看一个实例:
      
  1. import requests
    kw=input('请输入一个词语')
    params={
    'wd':kw
    }
    url='https://www.baidu.com/s'
    headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
    response=requests.get(url=url,params=params,headers=headers)
  2.  
  3. page_content=response.content #响应体的content是二进制的内容,text是文本内容
  4.  
  5. filename=kw+'.html'
    with open(filename,'wb') as f:
    f.write(response.content)
  1.   

  5.带coockies的请求

  1. import uuid
  2. import requests
  3.  
  4. url = 'http://httpbin.org/cookies' #这个网址可以做测试使用
  5. cookies = dict(sbid=str(uuid.uuid4()))
  6.  
  7. res = requests.get(url, cookies=cookies)
  8. print(res.text)

  6.带session对象的请求(比cookies好用)

  1. #实例化一个是session对象,session对象包含着cookies
  2. session=request.session()
    #session对象可以直接发起请求的
  3. session.get()
  4. session.post()

  7.request的post请求  

  1. 1. post请求和get请求大致相同:post(url,headers,data/jason)就是参数的名字不一样而已,get请求参数是在params字典里面,
    post请求参数在data或者jsaon里面(psot请求也可以有params参数,用来做跳转?next=)
      形式: requests.post(url="/login/",headers={},cookies={},params={"next":"index"},data={},json={})
  2.  
  3. 2.来看一个例子,爬取百度翻译的结果
  4.   
  5. import requests
  6. import json
  7. url='https://fanyi.baidu.com/sug'
  8. headers={
  9. 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'
  10. }
  11. kw=input('请输入一个词')
  12. data={
  13. 'kw':kw
  14. }
  15. response=requests.post(url=url,headers=headers,data=data)
  16. print(response.json())
  17.  
  18. 3,看一下jasoncontentype的区别
    import requests
    res1=requests.post(url='http://httpbin.org/post', data={'name':'yuan'}) #没有指定请求头,#默认的请求头:application/x-www-form-urlencoed
    print(res1.json())
  19.  
  20. res2=requests.post(url='http://httpbin.org/post',json={'age':"22",}) #默认的请求头:application/json
    print(res2.json())

{'args': {}, 'data': '', 'files': {}, 'form': {'name': 'yuan'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '9', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.21.0'}, 'json': None, 'origin': '121.35.181.66, 121.35.181.66', 'url': 'https://httpbin.org/post'}

{'args': {}, 'data': '{"age": "22"}', 'files': {}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '13', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.21.0'}, 'json': {'age': '22'}, 'origin': '121.35.181.66, 121.35.181.66', 'url': 'https://httpbin.org/post'}

  1.   

  8.request值ajax请求

  1. import requests
  2.  
  3. #url和参数,直接用抓包工具去请求头和Query String ParamMetres抓取
  4. url='https://movie.douban.com/j/chart/top_list'
  5. #因为是ajax发起的get请求,所以数据用params
  6. params={
  7. 'type':'',
  8. 'interval_id':'100:90',
  9. 'action':'',
  10. 'start': '',
  11. 'limit':''
  12. }
  13. headers={
  14. 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'
  15. }
  16. #从response看到Content-Type: application/json; charset=utf-8,说明是支持中文显示的
  17. jason_text=requests.get(url=url,headers=headers,params=params).text
  18. print(jason_text)

  9.request的ajax的post请求

  1. import requests
  2.  
  3. kw=input('请输入一个城市')
  4. #这边要记住,这是post请求,post请求不能不会把参数直接拼接在路径后面,所有网址拷过来就不要动了
  5. url='http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
  6. headers={
  7. 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'
  8. }
  9. # post请求用的是data,记得啊
  10. data={
  11. 'cname':'',
  12. 'pid': '',
  13. 'keyword': kw,
  14. 'pageIndex': '',
  15. 'pageSize': ''
  16. }
  17. #抓包工具能看到他是text类型,utf-8吧编码的,支持中文显示
  18. page_text=requests.post(url=url,headers=headers,data=data).text
  19. print(page_text)

  10.基于ajax的动态加载网址

  1. import requests
  2.  
  3. url='http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList'
  4. headers={
  5. 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'
  6. }
  7. #做循环作用的拿到所有页码的
  8. for i in range(100):
  9.  
  10. data={
  11. 'on': 'true',
  12. 'page': '',
  13. 'pageSize': '',
  14. 'productName':'',
  15. 'conditionType': i,
  16. 'applyname': '',
  17. 'applysn': ''
  18. }
  19. # #json()方法:返回是一个序列化号的json对象
  20. jason_text=requests.post(url=url,data=data,headers=headers).json()
  21. jason_list=jason_text['list']
  22. #拿到所有企业的id(ajax发出的post请求是根据企业id返回结果的)
  23. id_list=[]
  24. for dic in jason_list:
  25. id_list.append(dic['ID'])
  26. #发出第二次请求,带上企业id就能拿到具体的值了
  27. url1='http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById'
  28. for id in id_list:
  29. data1={
  30. 'id': id
  31. }
  32. json_text=requests.post(url=url1,data=data1,headers=headers).text
  33. print(json_text)

  11.带有代理的请求

  1. import requests
  2.  
  3. res=requests.get('http://httpbin.org/ip', proxies={'http':'111.177.177.87:9999'}).json()

三.reponse的属性

  1.常见属性

  1. import requests
  2. response=requests.get('https://www.jd.com/')
  3. print(response.status_code)
  4. print(response.text) #文本内容
  5. print(response.content) #二进制内容
  6. print(response.headers) #响应头
  7. print((response.cookies)) #响应的cookie
  8. print(response.cookies.get_dict())
  9. print(response.cookies.items())
  10. print(response.url) #响应的url
  11. print(response.history) #如果有重定向重定向之前相应的数据
  12. print(response.encoding) #响应体的编码

  2.编码问题

  1. import requests
  2. response=requests.get('http://www.autohome.com/news')
  3. response.encoding='gbk' #汽车之家网站返回的页面内容为gb2312编码的,而requests的默认编码为ISO-8859-1,如果不设置成gbk则中文乱码
  4. with open("res.html","w") as f: #解码过程是在拿text过程中执行的
  5. f.write(response.text)

  3.下载二进制内容

  1. import requests
  2. response=requests.get('http://bangimg1.dahe.cn/forum/201612/10/200447p36yk96im76vatyk.jpg')
  3. with open("res.png","wb") as f:
  4. # f.write(response.content) # 比如下载视频时,如果视频100G,用response.content然后一下子写到文件中是不合理的
  5. for line in response.iter_content(): #用迭代器可以一段一段,不知于把自己的硬盘搞垮了
  6. f.write(line)

  4,解析jason数据

  1. import requests
  2. import json
  3.  
  4. response=requests.get('http://httpbin.org/get')
  5. res1=json.loads(response.text) #太麻烦
  6. res2=response.json() #直接获取json数据,和上面的同理
  7. print(res1==res2)

  

  5. Redirection and History

  默认情况下,除了 HEAD, Requests 会自动处理所有重定向。可以使用响应对象的 history 方法来追踪重定向。Response.history 是一个 Response 对象的列表,

为了完成请求而创建了这些对象。这个对象列表按照从最老到最近的请求进行排序。

  1. >>> r = requests.get('http://github.com')
  2. >>> r.url
  3. 'https://github.com/'
  4. >>> r.status_code
  5. 200
  6. >>> r.history
  7. [<Response [301]>]

  另外,还可以通过 allow_redirects 参数禁用重定向处理:

  1. >>> r = requests.get('http://github.com', allow_redirects=False)
  2. >>> r.status_code
  3. 301
  4. >>> r.history
  5. []  

  6.相应状态码

    response.status_code

    #正常情况下我们是通过判断相应的状态码是不是200 来判断是否请求成功

    我们也可可以通过相应对象的方法来直接捕获状态码不是200的响应

  1.相应状态码不是200的

  1. import requests
  2.  
  3. bad_r = requests.get('http://httpbin.org/status/404')
  4. bad_r.status_code #
  5. bad_r.raise_for_status() #当响应的状态码不是200的时候调用这个接口,会抛出异常,哦我们呢捕获这个异常就好了
  6.  
  7. Traceback (most recent call last):
  8. File "<input>", line 1, in <module>
  9. File "D:\python37\lib\site-packages\requests\models.py", line 941, in raise_for_status
  10. raise HTTPError(http_error_msg, response=self)
  11. requests.exceptions.HTTPError: 404 Client Error: NOT FOUND for url: http://httpbin.org/status/404

  2.状态码是200

  1. import requests
  2. res=requests.get('https://www.baidu.com/')
  3. res.status_code #
  4. res.raise_for_status() #当响应的状态码是200的时候,调用这个接口的返回值的None
  5. print(res.raise_for_status())
  6. None

  3.判断响应状态码中和请求的状态码中的ok(200)是不是相等的

  

  1. importrequest
  2. res=requests.get('https://www.baidu.com/')
  3. res.status_code #
  4. res.status_code==requests.codes.ok
  5. True

所以通用的请求状态码判断这块可以这么写:

  1. import requests
  2.  
  3. try:
  4. res=requests.get('https://www.baidu.com/')
  5. res.raise_for_status()
  6.  
  7. except requests.HTTPError as error:
  8. print('status_error')
  9. except:
  10. print('other error')

  

  有一篇博文写的很简洁,可参考

爬虫初识和request使用的更多相关文章

  1. python爬虫如何POST request payload形式的请求

    python爬虫如何POST request payload形式的请求1. 背景最近在爬取某个站点时,发现在POST数据时,使用的数据格式是request payload,有别于之前常见的 POST数 ...

  2. 孤荷凌寒自学python第六十七天初步了解Python爬虫初识requests模块

    孤荷凌寒自学python第六十七天初步了解Python爬虫初识requests模块 (完整学习过程屏幕记录视频地址在文末) 从今天起开始正式学习Python的爬虫. 今天已经初步了解了两个主要的模块: ...

  3. 网络爬虫urllib:request之urlopen

    网络爬虫urllib:request之urlopen 网络爬虫简介 定义:按照一定规则,自动抓取万维网信息的程序或脚本. 两大特征: 能按程序员要求下载数据或者内容 能自动在网络上流窜(从一个网页跳转 ...

  4. Python urllib2写爬虫时候每次request open以后一定要关闭

    最近用python urllib2写一个爬虫工具,碰到运行一会程序后就会出现scoket connection peer reset错误.经过多次试验发现原来是在每次request open以后没有及 ...

  5. nodejs爬虫笔记(一)---request与cheerio等模块的应用

    目标:爬取慕课网里面一个教程的视频信息,并将其存入mysql数据库.以http://www.imooc.com/learn/857为例. 一.工具 1.安装nodejs:(操作系统环境:WiN 7 6 ...

  6. 爬虫模块介绍--request(发送请求模块)

    爬虫:可见即可爬   # 每个网站都有爬虫协议 基础爬虫需要使用到的三个模块 requests 模块  # 模拟发请求的模块 PS:python原来有两个模块urllib和urllib的升级urlli ...

  7. 爬虫之urllib.request基础使用(一)

    urllib模块 urllib模块简介: urllib提供了一系列用于操作URL的功能.包含urllib.request,urllib.error,urllib.parse,urllib.robotp ...

  8. Python做简单爬虫(urllib.request怎么抓取https以及伪装浏览器访问的方法)

    一:抓取简单的页面: 用Python来做爬虫抓取网站这个功能很强大,今天试着抓取了一下百度的首页,很成功,来看一下步骤吧 首先需要准备工具: 1.python:自己比较喜欢用新的东西,所以用的是Pyt ...

  9. Python爬虫--初识爬虫

    Python爬虫 一.爬虫的本质是什么? 模拟浏览器打开网页,获取网页中我们想要的那部分数据 浏览器打开网页的过程:当你在浏览器中输入地址后,经过DNS服务器找到服务器主机,向服务器发送一个请求,服务 ...

随机推荐

  1. oracle行转列练习

    ----------------------第一题--------------------------- create table STUDENT_SCORE ( name ), subject ), ...

  2. 算法Sedgewick第四版-第1章基础-013一用stack实现自动补全表达式括号

    package algorithms.exercise; import algorithms.ADT.Stack; import algorithms.util.StdIn; import algor ...

  3. hive与hbase数据类型对应关系

    hive与hbase数据类型对应关系 当hbase中double,int 类型以byte方式存储时,用字符串取出来必然是乱码. 在hivd与hbase整合时也遇到这个问题:做法是:#b 1.加#b C ...

  4. Luogu U15118 萨塔尼亚的期末考试(fail)

    感觉...昨天是真的傻... 题意 T个询问,每个询问给一个n,求 $ \frac{\sum_{n}^{i = 1}Fib_{i} * i}{n * (n + 1) / 2} $ Fib是斐波那契数列 ...

  5. C++面试笔记--排序

    这里我们开始复习排序的一些面试题. 首先我们来看一下各个排序方法的时间复杂度和稳定性的比较,见下面表格: 排序法 平均时间 最差情形 稳定度 额外空间 备注 冒泡 O(n2)     O(n2) 稳定 ...

  6. mysql双机热备份的实现步骤

    MySQL 提供了数据库的同步功能,这对我们实现数据库的冗灾.备份.恢复.负载均衡等都是有极大帮助的.本文描述了常见的同步设置方法.<?xml:namespace prefix = o /> ...

  7. Linux系统命令Top/free的使用及参数详解

    1.作用 top命令用来显示执行中的程序进程,使用权限是所有用户. 2.格式 top [-] [d delay] [q] [c] [S] [s] [i] [n] 3.主要参数 d:指定更新的间隔,以秒 ...

  8. TinkerPop中的遍历:图的遍历步骤(1/3)

    图遍历步骤(Graph Traversal Steps) 在最一般的层次上,Traversal<S,E>实现了Iterator,S代表起点,E代表结束.遍历由四个主要组成部分组成: Ste ...

  9. Java之封装特性

    Java中的三大特性:继承,封装,多态: 其中封装概念:封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口. 面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治.封装的 对象 ...

  10. 基于jQuery的Tooltip

    近来,要开发一个关务管理系统,为了增加系统美观度,自己开发了一个基于jQuery框的的小插件,与大家分享一下,希望大家能给我提出宝贵修改意见. 下面开发说明使用方法和内容: 一.引用jQuery框架, ...