Python网络爬虫 第一章 入门

一、爬⾍概述

什么是爬⾍?


不知道各位是否遇到过这样的需求. 就是我们总是希望能够保存互联⽹上的⼀些重要的数据信息为⼰所⽤.⽐如,

  • 在浏览到⼀些优秀的让⼈⾎脉喷张的图⽚时. 总想保存起来留为⽇后做桌⾯上的壁纸
  • 在浏览到⼀些重要的数据时(各⾏各业), 希望保留下来⽇后为⾃⼰进⾏各种销售⾏为增光添彩
  • 在浏览到⼀些奇奇怪怪的劲爆视频时, 希望保存在硬盘⾥供⽇后慢慢品鉴
  • 在浏览到⼀些⼗分优秀的歌声曲⽬时, 希望保存下来供我们在烦闷的⽣活中增添⼀份精彩

爬⾍和Python

爬⾍⼀定要⽤Python么? ⾮也~ ⽤Java也⾏, C也可以. 请各位记住,编程语⾔只是⼯具. 抓到数据是你的⽬的. ⽤什么⼯具去达到你的⽬的都是可以的. 和吃饭⼀样, 可以⽤叉⼦也可以⽤筷⼦, 最终的结果都是你能吃到饭. 那为什么⼤多数⼈喜欢⽤Python呢? 答案: 因为Python写爬⾍简单. 不理解? 问: 为什么吃⽶饭不⽤⼑叉? ⽤筷⼦?因为简单! 好⽤! ⽽Python是众多编程语⾔中, ⼩⽩上⼿最快, 语法最简单. 更重要的是, 这货有⾮常多的关于爬⾍能⽤到的第三⽅⽀持库. 说直⽩点⼉. 就是你⽤筷⼦吃饭, 我还附送你⼀个佣⼈. 帮你吃! 这样吃的是不是更爽了. 更容易了~

爬⾍合法么?

⾸先, 爬⾍在法律上是不被禁⽌的. 也就是说法律是允许爬⾍存在的.但是, 爬⾍也具有违法⻛险的. 就像菜⼑⼀样, 法律是允许菜⼑的存在的. 但是你要是⽤来砍⼈, 那对不起. 没⼈惯着你. 就像王欣说过的,技术是⽆罪的. 主要看你⽤它来⼲嘛. ⽐⽅说有些⼈就利⽤爬⾍+⼀些⿊客技术每秒钟对着bilibili撸上⼗万⼋千次. 那这个肯定是不被允许的.爬⾍分为善意的爬⾍和恶意的爬⾍

  • 善意的爬⾍, 不破坏被爬取的⽹站的资源(正常访问, ⼀般频率不⾼, 不窃取⽤户隐私)
  • 恶意的爬⾍, 影响⽹站的正常运营(抢票, 秒杀, 疯狂solo⽹站资源造成⽹站宕机)

综上, 为了避免进局子!我们还是要安分守⼰. 时常优化⾃⼰的爬⾍程序避免⼲扰到⽹站的正常运⾏. 并且在使⽤爬取到的数据时,发现涉及到⽤户隐私和商业机密等敏感内容时, ⼀定要及时终⽌爬取和传播

爬⾍的⽭与盾

反爬机制 ⻔户⽹站,可以通过制定相应的策略或者技术⼿段,防⽌爬⾍程序进⾏⽹站数据的爬取。

反反爬策略 爬⾍程序可以通过制定相关的策略或者技术⼿段,破解⻔户⽹站中具备的反爬机制,从⽽可以获取⻔户⽹站中相关的数据。
robots.txt协议: 君⼦协议。规定了⽹站中哪些数据可以被爬⾍爬取 哪些数据不可以被爬取。

 

 

二、第一个爬虫

⾸先,我们还是需要回顾⼀下爬⾍的概念. 爬⾍就是我们通过我们写的程序去抓取互联⽹上的数据资源. ⽐如, 此时我需要百度的资源. 在不考虑爬⾍的情况下, 我们肯定是打开浏览器, 然后输⼊百度的⽹址,紧接着, 我们就能在浏览器上看到百度的内容了. 那换成爬⾍呢? 其实道理是⼀样的. 只不过, 我们需要⽤代码来模拟⼀个浏览器, 然后同样的输⼊百度的⽹址. 那么我们的程序应该也能拿到百度的内容. 对 吧~ 在python中, 我们可以直接⽤urllib模块来完成对浏览器的模拟⼯作~,
直接上代码

from urllib.request import urlopen
resp = urlopen("http://www.baidu.com") # 打开 百度
print(resp.read().decode("utf-8")) # 打印 抓取到的
内容

是不是很简单呢?
我们可以把抓取到的html内容全部写⼊到⽂件中, 然后和原版的百度进⾏对⽐, 看看是否⼀致

# 爬虫: 通过编写程序来获取到互联网上的资源
# 百度
# 需求: 用程序模拟浏览器. 输入一个网址. 从该网址中获取到资源或者内容
# python搞定以上需求. 特别简单
from urllib.request import urlopen

url = "http://www.baidu.com"
resp = urlopen(url)

with open("mybaidu.html", mode="w") as f:
    f.write(resp.read().decode("utf-8"))  # 读取到网页的页面源代码
print("over!")

三、web请求全过程剖析

上⼀⼩节我们实现了⼀个⽹⻚的整体抓取⼯作. 那么本⼩节, 给各位好好剖析⼀下web请求的全部过程, 这样有助于后⾯我们遇到的各种各样的⽹站就有了⼊⼿的基本准则了.

那么到底我们浏览器在输⼊完⽹址到我们看到⽹⻚的整体内容, 这个过程中究竟发⽣了些什么?

这⾥我们以百度为例. 在访问百度的时候, 浏览器会把这⼀次请求发送到百度的服务器(百度的⼀台电脑), 由服务器接收到这个请求, 然后加载⼀些数据. 返回给浏览器, 再由浏览器进⾏显示. 听起来好像是个
废话...但是这⾥蕴含着⼀个极为重要的东⻄在⾥⾯, 注意, 百度的服务器返回给浏览器的不直接是⻚⾯, ⽽是⻚⾯源代码(由html, css, js组成). 由浏览器把⻚⾯源代码进⾏执⾏, 然后把执⾏之后的结果展示给⽤户. 所以我们能看到在上⼀节的内容中,我们拿到的是百度的源代码(就是那堆看不懂的⻤东⻄). 具体过程如图.

接下来就是⼀个⽐较重要的事情了. 所有的数据都在⻚⾯源代码⾥么? ⾮也~ 这⾥要介绍⼀个新的概念

那就是⻚⾯渲染数据的过程, 我们常⻅的⻚⾯渲染过程有两种,

1. 服务器渲染

这个最容易理解, 也是最简单的. 含义呢就是我们在请求到服务器的时候, 服务器直接把数据全部写⼊到html中, 我们浏览器就能直接拿到带有数据的html内容. ⽐如,

由于数据是直接写在html中的, 所以我们能看到的数据都在⻚⾯源代码中能找的到的,这种⽹⻚⼀般都相对⽐较容易就能抓取到⻚⾯内容.

2. 前端JS渲染

这种就稍显麻烦了. 这种机制⼀般是第⼀次请求服务器返回⼀堆HTML框架结构. 然后再次请求到真正保存数据的服务器, 由这个服务器返回数据, 最后在浏览器上对数据进⾏加载. 就像这样:

这样做的好处是服务器那边能缓解压⼒. ⽽且分⼯明确. ⽐较容易维护. 典型的有这么⼀个⽹⻚

那数据是何时加载进来的呢? 其实就是在我们进⾏⻚⾯向下滚动的时候, jd就在偷偷的加载数据了, 此时想要看到这个⻚⾯的加载全过程, 我们就需要借助浏览器的调试⼯具了(F12)

看到了吧, ⻚⾯上看到的内容其实是后加载进来的.
OK, 在这⾥我不是要跟各位讲jd有多⽜B, 也不是说这两种⽅式有什么不同, 只是想告诉各位, 有些时候, 我们的数据不⼀定都是直接来⾃于⻚⾯源代码. 如果你在⻚⾯源代码中找不到你要的数据时, 那很可能数据是存放在另⼀个请求⾥。

四、HTTP协议

协议: 就是两个计算机之间为了能够流畅的进⾏沟通⽽设置的⼀个君⼦协定. 常⻅的协议有TCP/IP. SOAP协议, HTTP协议, SMTP协议等
等.....
HTTP协议, Hyper Text Transfer Protocol(超⽂本传输协议)的缩写,是⽤于从万维⽹(WWW:World Wide Web )服务器传输超⽂本到本地浏览器的传送协议. 直⽩点⼉, 就是浏览器和服务器之间的数据交互遵守的就是HTTP协议.
HTTP协议把⼀条消息分为三⼤块内容. ⽆论是请求还是响应都是三块内容
请求:

请求⾏ -> 请求⽅式(get/post) 请求url地址 协议
请求头 -> 放⼀些服务器要使⽤的附加信息
请求体 -> ⼀般放⼀些请求参数
响应:
状态⾏ -> 协议 状态码
响应头 -> 放⼀些客户端要使⽤的⼀些附加信息
响应体 -> 服务器返回的真正客户端要⽤的内容(HTML,json)等

在后⾯我们写爬⾍的时候要格外注意请求头和响应头. 这两个地⽅⼀般都隐含着⼀些⽐较重要的内容

请求头中最常⻅的⼀些重要内容(爬⾍需要):

  • User-Agent : 请求载体的身份标识(⽤啥发送的请求)
  • Referer: 防盗链(这次请求是从哪个⻚⾯来的? 反爬会⽤到)
  • cookie: 本地字符串数据信息(⽤户登录信息, 反爬的token)

响应头中⼀些重要的内容:

  • cookie: 本地字符串数据信息(⽤户登录信息, 反爬的token)
  • 各种神奇的莫名其妙的字符串(这个需要经验了, ⼀般都是token字样, 防⽌各种攻击和反爬)

请求⽅式:
GET: 显示提交
POST: 隐示提交

五、requests模块⼊⻔

在前⾯⼩节中, 我们使⽤urllib来抓取⻚⾯源代码. 这个是python内置的⼀个模块. 但是, 它并不是我们常⽤的爬⾍⼯具. 常⽤的抓取⻚⾯的模块通常使⽤⼀个第三⽅模块requests. 这个模块的优势就是⽐urllib
还要简单, 并且处理各种请求都⽐较⽅便.既然是第三⽅模块, 那就需要我们对该模块进⾏安装, 安装⽅法:

pip install requests

如果安装速度慢的话可以改⽤国内的源进⾏下载安装.

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests

OK. 接下来我们来看看requests能带给我们什么?
先拿sogou开⼑试试

# 案例1. 抓取搜狗搜索内容
import requests
query = input("输入一个你喜欢的明星")

url = f'https://www.sogou.com/web?query={query}'

dic = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
}

resp = requests.get(url, headers=dic)  # 处理一个小小的反爬

print(resp)#相应状态200
print(resp.text)  # 拿到页面源代码
resp.close()#关闭resp

接下来, 我们看⼀个稍微复杂那么⼀丢丢的, 百度翻译~
注意百度翻译这个url不好弄出来. 记住, 在输⼊的时候, 关掉各种输⼊法,要⽤英⽂输⼊法, 然后不要回⻋. 就能看到这个sug了

# 案例2.抓取百度翻译数据
import requests

url = "https://fanyi.baidu.com/sug"

s = input("请输入你要翻译的英文单词:")
dat = {
    "kw": s
}

# 发送post请求, 发送的数据必须放在字典中, 通过data参数进行传递
resp = requests.post(url, data=dat)
# 返回值是json 那就可以直接解析成json
# {'errno': 0, 'data': [{'k': 'Apple', 'v': 'n. 苹果公司,原称苹果电脑公司'}, {'k': 'apple', 'v': 'n. 苹果; 苹果公司; 苹果树'}, {'k': 'APPLE', 'v': 'abbr. applied parallel programming language 应用并行程序'}, {'k': 'apples', 'v': 'n. 苹果,苹果树( apple的名词复数 ); [美国口语]棒球; [美国英语][保龄球]坏球; '}, {'k': 'Apples', 'v': '[地名] [瑞士] 阿普勒'}]}
resp_json = resp.json()
print(resp_json['data'][0])  # 将服务器返回的内容直接处理成json()  => dict
resp.close()#关闭resp

是不是很顺⼿呢? 还有⼀些⽹站在进⾏请求的时候会校验你的客户
端设备型号. ⽐如, 我们抓取⾖瓣电影

XMLHttpRequest (XHR) 是一种创建 AJAX 请求的 JavaScript API 。它的方法提供了在浏览器和服务器之间发送请求的能力。

 

 

# 案例3: 抓取⾖瓣电影
import requests

url = "https://movie.douban.com/j/chart/top_list"

# url ="https://movie.douban.com/j/chart/top_list?type=24&interval_id=100%3A90&action=&start=0&limit=20"
# url参数过长,使用第二种方式来封装参数

# 重新封装参数 字典
param = {
    "type": "24",
    "interval_id": "100:90",
    "action": "",
    "start": 0,
    "limit": 20,
}

headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
}
#get 请求参数params
resp = requests.get(url=url, params=param, headers=headers)

print(resp.json())
resp.close()#关闭resp

OK~ 本章和本⼩节的内容就这么多了. 简单回顾⼀下本章内容

  • 1. 爬⾍就是写程序去模拟浏览器⽤来抓取互联⽹上的内容
  • 2. python中⾃带了⼀个urllib提供给我们进⾏简易爬⾍的编写
  • 3. requests模块的简单使⽤, 包括get, post两种⽅式的请求. 以及User-Agent的介绍
posted @ 2018-08-18 16:25  王陸  阅读(733)  评论(0编辑  收藏  举报