一、爬虫简介

1、介绍

网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

实际上就是一段自动抓取互联网信息的程序,它会从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止,然后把数据解析成对我们有价值的信息。

2、爬虫的价值

互联网中最有价值的便是数据,比如天猫、京东、淘宝等电商网站超越咨询顾问的算力,在用户理解和维护,抓取各大电商的评论及销量数据,对各种商品(颗粒度可到款式)沿时间序列的销量以及用户的消费场景进行分析,
又或者58同城的房产、安居客、Q房网、搜房等房产网站下半年深圳房价将如何发展 ,抓取房产买卖及租售信息,对热热闹闹的房价问题进行分析。

大众点评、美团网等餐饮及消费类网站黄焖鸡米饭是怎么火起来的?抓取各种店面的开业情况以及用户消费和评价,了解周边变化的口味,所谓是“舌尖上的爬虫”。以及各种变化的口味,比如:啤酒在衰退,重庆小面在崛起。

拉勾网、中华英才网等招聘网站互联网行业哪个职位比较有前途?抓取各类职位信息,分析最热门的职位以及薪水。

这些数据都代表了各个行业的重点方向,可以说,谁掌握了行业内的第一手数据,谁就拥有比别人更大的机会成为主宰。

3、robots.txt协议

Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。

robots.txt 是网站和搜索引擎的协议的纯文本文件。当一个搜索引擎蜘蛛来访问站点时,它首先爬行来检查该站点根目录下是否存在robots.txt,如果存在,根据文件内容来确定访问范围,如果没有,蜘蛛就沿着链接抓取。robots.txt 放在项目的根目录下。

但值得注意的是,该协议只是相当于口头的协议,并没有使用相关技术进行强制管制,如果你不想遵守,有这个协议也没用的,
为了防止被爬,只能在自己的网站上进行相关的反爬技术。

4、爬虫的基本流程

5、http协议

https://www.cnblogs.com/Zzbj/p/9844520.html

二、requests模块

Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,Requests它会比urllib更加方便,可以节约我们大量的工作。
requests本质就是封装了urllib3,requests是python实现的最简单易用的HTTP库,建议爬虫使用requests库。

1、requests模块支持的请求

  1. import requests
  2. requests.get("http://httpbin.org/get")
  3. requests.post("http://httpbin.org/post")
  4. requests.put("http://httpbin.org/put")
  5. requests.delete("http://httpbin.org/delete")
  6. requests.head("http://httpbin.org/get")
  7. requests.options("http://httpbin.org/get") 

2、get请求

  1. 1. 基本请求
  2. import requests
  3. response = requests.get('https://www.jd.com/') # 发送一个get请求
  4.  
  5. with open("jd.html", "wb") as f:
  6. f.write(response.content) # 把响应体(response.content)保存到一个文件中
  7.  
  8. 2. 含参数请求
  9. import requests
  10. # 通过params给请求添加参数
  11. response = requests.get(
  12. 'https://s.taobao.com/search',
  13. params={
  14. "q": "手机",
  15. })
  16.  
  17. with open("shouji.html", "w", encoding="utf8") as f:
  18. f.write(response.text) # 把响应体保存到一个文件中(w模式用text,wb模式用content)
  19.  
  20. 3. 含请求头请求
  21. import requests
  22. response = requests.get(
  23. 'https://dig.chouti.com/',
  24. headers={
  25. 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36',
  26. })
  27.  
  28. with open("ct.html", "wb") as f:
  29. f.write(response.content) # 把响应体(response.content)保存到一个文件中
  30.  
  31. 通过headers给请求添加请求头,有些网站为了反爬会设置一些"障碍",如果你User-Agent这个请求头为空,他们就认为你是机器人,
  32. 就不接受你的请求,简单地实现反爬。
  33.  
  34. 4. cookies请求
  35. import uuid
  36. import requests
  37.  
  38. url = 'http://httpbin.org/cookies'
  39. cookies = dict(sbid=str(uuid.uuid4()))
  40.  
  41. response = requests.get(url, cookies=cookies)
  42. print(response.text)
  43.  
  44. 5. requests.session()
  45. import requests
  46.  
  47. res = requests.get("https://github.com/login") # 请求登录页面
  48. print(res.cookies.get_dict()) # 获取到服务器传过来的cookies
  49. res = requests.post("https://github.com/session", cookies=res.cookies.get_dict()) # 爬取需要登录的页面,带上cookies
  50.  
  51. session = requests.session() # 使用requests.session()方法
  52. # 下面在使用requests的地方,直接使用session即可,session就会保存服务器发送过来的cookie信息
  53. res2 = session.get("https://github.com/login")
  54. print(session.cookies.get_dict())
  55. # 这里用了session后,不需要再提交cookies,默认已经带着cookies了,等同于上面的requests.post带上cookies
  56. res3 = session.post("https://github.com/session")

3、post请求

  1. . data参数
  2. requests.post()用法与requests.get()完全一致,不同的是requests.post()多了一个data参数,用来存放请求体数据,
  3. 请求体数据使用data,没有指定请求头,默认的请求头的contentType=application/x-www-form-urlencoed
  4.  
  5. import requests
  6. response = requests.post(
  7. "http://httpbin.org/post",
  8. params={
  9. "pag": 1
  10. },
  11. data={
  12. "user": "zzz",
  13. "pwd": ''
  14. })
  15.  
  16. print(response.text)
  17.  
  18. 2. 发送json数据
  19. import requests
  20. response = requests.post(
  21. "http://httpbin.org/post",
  22. params={
  23. "pag": 1
  24. },
  25. json={
  26. "user": "zzz",
  27. "pwd": ''
  28. })
  29.  
  30. print(response.text)
  31.  
  32. 请求体数据指定时使用json,请求头的contentType=application/json
  33.  
  34. . urlencoedjson格式的区别
  35. urlencoed是浏览器默认的格式,格式是:
  36. a=1&b=2
  37.  
  38. json的格式是:
  39. xxx = {
  40. "a" = "",
  41. "b" = ""
  42. }

4、response对象

1. 常用属性

  1. import requests
  2.  
  3. response = requests.get('https://sh.lianjia.com')
  4. # response属性
  5. print(response.text) # 获取响应的内容(字符串)
  6. print(response.content) # 获取响应的内容(字节)
  7. print(response.status_code) # 获取响应的状态码
  8. print(response.headers) # 获取响应头的信息
  9. print(response.cookies) # 获取服务器传过来的cookies
  10. print(response.cookies.get_dict()) # 把cookies转换成字典格式
  11. print(response.cookies.items()) # 跟字典的items方法一样
  12. print(response.url) # 获取请求的url
  13. print(response.history) # 获取请求的重定向历史
  14. print(response.encoding) # 获取响应的编码

2.response.text和response.content

  1. response.text拿到的是响应的字符串
  2. response.content拿到的是响应的字节串
  3.  
  4. text(字符串)就是把content(字节)默认用utf8给解码了而已,但是如果爬到的内容编码模式不是utf8,那么用text拿到的内容就会有乱码了。

3. 编码问题

  1. 方法一:指定响应的编码
  2. import requests
  3.  
  4. response = requests.get('http://www.autohome.com/news')
  5. response.encoding = 'gbk' # 汽车之家网站返回的页面内容为gb2312编码的,而requests的默认编码为ISO-8859-1,如果不设置成gbk则中文乱码
  6. with open("qczj.html", "w") as f:
  7. f.write(response.text) # 把解码后的文本写入文件中
  8.  
  9. 方法二:直接使用wb模式写入
  10. import requests
  11.  
  12. response = requests.get('http://www.autohome.com/news')
  13. with open("qczj2.html", "wb") as f:
  14. f.write(response.content) # 以字节形式写入文件中

4. history重定向

  1. 默认情况下,除了HEAD, Requests会自动处理所有重定向。可以使用响应对象的 history 方法来追踪重定向。
  2. Response.history 是一个 Response 对象的列表,为了完成请求而创建了这些对象。这个对象列表按照从最老到最近的请求进行排序。
  3.  
  4. import requests
  5.  
  6. response = requests.get("https://www.autohome.com.cn/huizhou/")
  7. print(response.status_code) #
  8. print(response.history) # 没有重定向为空列表:[]
  9.  
  10. # allow_redirects默认为True,当网站是https协议,而你输入了http协议,就会自动重定向到https
  11. # 把allow_redirects设置了False,请求http,可以看到response响应就是重定向
  12. response = requests.get("http://www.autohome.com.cn/huizhou/", allow_redirects=False)
  13. print(response.status_code) #
  14. print(response) # 重定向的对象:<Response [302]>
  15.  
  16. # 也可以让allow_redirects为True,查看响应体的history,看是否有重定向
  17. response = requests.get("http://www.autohome.com.cn/huizhou/", allow_redirects=True)
  18. print(response.status_code) #
  19. print(response.history) # [<Response [302]>]

5. 下载二进制文件

  1. import requests
  2.  
  3. response = requests.get('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1548171900434&di=04e4eb6ee17c081556947ebb1ceb161e&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F039e4e47e1a2a53f305a83a367b511570b8e96771d98d-wWPJMp_fw658')
  4. with open("wuming.png","wb") as f:
  5. # f.write(response.content) # 如果下载的是视频,而且有100G,用response.content会把内容一下全部写到文件中,是不合理的
  6. for line in response.iter_content(): # response.iter_content()方法是把响应内容转换成迭代器
  7. f.write(line)

6.解析json数据

  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. 代理

  1. 一些网站会有相应的反爬虫措施,例如很多网站会检测某一段时间某个IP的访问次数,如果访问频率太快以至于看起来不像正常访客,
  2. 它可能就会会禁止这个IP的访问。所以我们需要设置一些代理服务器,每隔一段时间换一个代理,就算IP被禁止,依然可以换个IP继续爬取。
  3.  
  4. import requests
  5.  
  6. proxies = {
  7. "http": "http://117.70.39.242:9999",
  8. }
  9.  
  10. response = requests.get("http://httpbin.org/ip",proxies=proxies)
  11. print(response.text)

三、爬虫案例

1、爬取豆瓣top250

  1. import requests
  2. import re
  3. import json
  4. import time
  5. from concurrent.futures import ThreadPoolExecutor
  6. pool = ThreadPoolExecutor(5) # 线程池
  7.  
  8. # 获取豆瓣top250所有电影的名称,url,评分,评论数
  9.  
  10. # 1.发送请求,获取响应
  11. def getPage(url):
  12. response = requests.get(url)
  13. return response.text
  14.  
  15. # 2.解析数据
  16. def parsePage(res):
  17. com = re.compile('<div class="item">.*?<a href="(?P<url>.*?)">.*?<span class="title">(?P<title>.*?)</span>.*?<span class="rating_num".*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)人评价</span>',re.S)
  18. iter_result = com.finditer(res)
  19. return iter_result
  20.  
  21. # 3. 存储数据
  22. def stored(iter_result):
  23. # 存储文件中
  24. movie_info = {}
  25. for i in iter_result:
  26. print("OK")
  27. print(i.group("url"))
  28. print(i.group("title"))
  29. print(i.group("rating_num"))
  30. print(i.group("comment_num"))
  31.  
  32. movie_info["url"] = i.group("url")
  33. movie_info["title"] = i.group("title")
  34. movie_info["rating_num"] = i.group("rating_num")
  35. movie_info["comment_num"] = i.group("comment_num")
  36.  
  37. with open("doubanTop250.txt", 'a', encoding="utf8") as f:
  38. f.write(json.dumps(movie_info, ensure_ascii=False)+"\n")
  39.  
  40. def spider_movie(url):
  41. res = getPage(url)
  42. iter_result = parsePage(res)
  43. stored(iter_result)
  44.  
  45. def main():
  46. for i in range(10):
  47. url = "https://movie.douban.com/top250?start=%s&filter=" % (i*25)
  48. pool.submit(spider_movie, url)
  49.  
  50. if __name__ == '__main__':
  51. start = time.time()
  52. main()
  53. end = time.time()
  54. print("cost time:", end - start)

1. 常规方法

  1. import requests
  2. import re
  3. import json
  4. import time
  5. from concurrent.futures import ThreadPoolExecutor
  6. pool = ThreadPoolExecutor(5) # 线程池
  7.  
  8. # 获取豆瓣top250所有电影的名称,url,评分,评论数
  9.  
  10. # 1.发送请求,获取响应
  11. def getPage(url):
  12. response = requests.get(url)
  13. return response.text
  14.  
  15. # 2.解析数据
  16. def parsePage(res):
  17. com = re.compile('<div class="item">.*?<a href="(?P<url>.*?)">.*?<span class="title">(?P<title>.*?)</span>.*?<span class="rating_num".*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)人评价</span>',re.S)
  18. iter_result = com.finditer(res)
  19. return iter_result
  20.  
  21. # 使用生成器处理数据
  22. def movieInfo(iter_result):
  23. for i in iter_result:
  24. yield {
  25. "url": i.group("url"),
  26. "title": i.group("title"),
  27. "rating_num": i.group("rating_num"),
  28. "comment_num": i.group("comment_num"),
  29. }
  30.  
  31. # 3. 存储数据
  32. def stored(info):
  33. with open("doubanTop250.txt", 'a', encoding="utf8") as f:
  34. for i in info:
  35. data = json.dumps(i, ensure_ascii=False)
  36. f.write(data+"\n")
  37.  
  38. def spider_movie(url):
  39. res = getPage(url)
  40. iter_result = parsePage(res)
  41. info = movieInfo(iter_result)
  42. stored(info)
  43.  
  44. def main():
  45. for i in range(10):
  46. url = "https://movie.douban.com/top250?start=%s&filter=" % (i*25)
  47. pool.submit(spider_movie, url)
  48.  
  49. if __name__ == '__main__':
  50. start = time.time()
  51. main()
  52. end = time.time()
  53. print("cost time:", end - start)

2.使用生成器(当数据很多的时候)

2、爬取GitHub登录后的home页面

  1. '''
  2. github的反爬策略是,必须带登录界面github给你的authenticity_token
  3. 必须带cookies
  4. 必须带上登录的数据
  5. '''
  6. import requests
  7. import re
  8.  
  9. # 第一步: 请求登录页面,获取token,以便通过post请求校验
  10. session = requests.session() # 用requests.session保存cookies,下面post请求就不需要再指定cookies了
  11. res = session.get("https://github.com/login")
  12.  
  13. # res = requests.get("https://github.com/login")
  14. # cookies = res.cookies.get_dict()
  15.  
  16. authenticity_token = re.findall('name="authenticity_token" value="(.*?)"', res.text)[0]
  17. print(authenticity_token)
  18.  
  19. # 第二步:构建post请求数据
  20. data = {
  21. "commit": "Sign in",
  22. "utf8": "✓",
  23. "authenticity_token": authenticity_token,
  24. "login": "your name", # 你github的账号
  25. "password": "your password" # 你github的密码
  26. }
  27.  
  28. headers = {
  29. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36',
  30. }
  31.  
  32. # 如果没有使用requests.session,需要带上cookies=cookies
  33. # res = requests.post("https://github.com/session", data=data, headers=headers, cookies=cookies)
  34. res = session.post("https://github.com/session", data=data, headers=headers)
  35.  
  36. with open("github.html", "wb") as f:
  37. f.write(res.content)

爬虫与request模块的更多相关文章

  1. 爬虫之request模块高级

    一.cookie&session cookie:服务器端使用cookie来记录客户端的状态信息 实现流程: 执行登陆操作(获取cookie) 在发起个人主页请求时,需要将cookie携带到该请 ...

  2. 【nodejs】理想论坛帖子下载爬虫1.07 使用request模块后稳定多了

    在1.06版本时,访问网页采用的时http.request,但调用次数多以后就问题来了. 寻找别的方案时看到了https://cnodejs.org/topic/53142ef833dbcb076d0 ...

  3. 爬虫之urllib包以及request模块和parse模块

    urllib简介 简介 Python3中将python2.7的urllib和urllib2两个包合并成了一个urllib库 Python3中,urllib库包含有四个模块: urllib.reques ...

  4. asynicio模块以及爬虫应用asynicio模块(高性能爬虫)

    一.背景知识 爬虫的本质就是一个socket客户端与服务端的通信过程,如果我们有多个url待爬取,只用一个线程且采用串行的方式执行,那只能等待爬取一个结束后才能继续下一个,效率会非常低. 需要强调的是 ...

  5. 第三百二十六节,web爬虫,scrapy模块,解决重复ur——自动递归url

    第三百二十六节,web爬虫,scrapy模块,解决重复url——自动递归url 一般抓取过的url不重复抓取,那么就需要记录url,判断当前URL如果在记录里说明已经抓取过了,如果不存在说明没抓取过 ...

  6. 第三百二十五节,web爬虫,scrapy模块标签选择器下载图片,以及正则匹配标签

    第三百二十五节,web爬虫,scrapy模块标签选择器下载图片,以及正则匹配标签 标签选择器对象 HtmlXPathSelector()创建标签选择器对象,参数接收response回调的html对象需 ...

  7. 第三百二十四节,web爬虫,scrapy模块介绍与使用

    第三百二十四节,web爬虫,scrapy模块介绍与使用 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了 ...

  8. python实战——网络爬虫之request

    Urllib库是python中的一个功能强大的,用于操做URL,并在做爬虫的时候经常要用到的库,在python2中,分为Urllib和Urllib2两个库,在python3之后就将两个库合并到Urll ...

  9. Python爬虫教程-09-error 模块

    Python爬虫教程-09-error模块 今天的主角是error,爬取的时候,很容易出现错,所以我们要在代码里做一些,常见错误的处,关于urllib.error URLError URLError ...

随机推荐

  1. Object.keys 及表单清空

    Object.keys 返回一个所有元素为字符串的数组,其元素来自于从给定的object上面可直接枚举的属性.这些属性的顺序与手动遍历该对象属性时的一致. // simple array var ar ...

  2. How to Apply Patches to a WLS 8.1 Environment

    APPLIES TO: Oracle Weblogic Server - Version 8.1 to 8.1Information in this document applies to any p ...

  3. Node的简介

    从开始学习node到现在已经有半年多了,中间没有做过什么实际工作中的项目,所以感觉自己的知识有些匮乏,但是我还是要写这些文章,因为工作中的需要用node来开发后台环境,再加上我对这些知识记得不多,都是 ...

  4. 预置第三方apk到MTK项目相关问题总结

    目前5.0之后项目预置方式通用步骤为: 建立apk文件夹;  置目标apk到该文件夹下;   解压缩apk查看是否包含lib/文件夹(apk项目是否包含lib库文件);  在该文件夹下编写Androi ...

  5. UDK命令

    UDK命令行参数与控制台命令都是大小写不敏感的 命令行  udn中文  udn英文 全词大小写匹配,正则表达式,在c++代码中搜索减号开头的命令行参数(如:-BENCHMARK.-onethread等 ...

  6. Python+ITchart实现微信中男女比例,城市分布统计并可视化显示

    直接上代码: import itchat import os import csv import pandas as pd from pyecharts import Bar,Pie,Geo impo ...

  7. Ehcache入门经典:第二篇ehcache.xml的参数

    继续第一篇 diskStorepath:指定在硬盘上存储对象的路径path属性可以配置的目录有: user.home(用户的家目录) user.dir(用户当前的工作目录) java.io.tmpdi ...

  8. Nagle 算法

    1. Nagel算法        TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认.为了尽可能的利用网络带宽,TCP总是希望尽可能的发 ...

  9. EntityFramework Code-First 简易教程(六)-------领域类配置之DataAnnotations

    EF Code-First提供了一个可以用在领域类或其属性上的DataAnnotation特性集合,DataAnnotation特性会覆盖默认的EF约定. DataAnnotation存在于两个命名空 ...

  10. iOS 常用三方(持续更新)

    iOS 常用三方 1.ZWMSegmentController 分页控制器 https://github.com/weiming4219/ZWMSegmentController