爬虫的基本原理

所谓爬虫就是一个自动化数据采集工具,你只要告诉它要采集哪些数据。其背后的基本原理就是爬虫程序向目标服务器发起 HTTP 请求,然后目标服务器返回响应结果,爬虫客户端收到响应并从中提取数据,再进行数据清洗、数据存储工作。

python爬虫大数据采集与挖掘电子书 python3网络爬虫数据采集_python爬虫大数据采集与挖掘电子书

Http请求格式和响应格式

python爬虫大数据采集与挖掘电子书 python3网络爬虫数据采集_python_02


python爬虫大数据采集与挖掘电子书 python3网络爬虫数据采集_服务器_03

用Pyton内建模块 urllib 请求一个 URL 代码示例如下:

import ssl

from urllib.request import Request
from urllib.request import urlopen

# 创建一个未验证的上下文
context = ssl._create_unverified_context()

# HTTP 请求
request = Request(url="https://foofish.net/pip.html",
                  method="GET",
                  headers={"Host": "foofish.net"},
                  data=None)

# HTTP 响应
response = urlopen(request, context=context)
headers = response.info()  # 响应头
content = response.read()  # 响应体
code = response.getcode()  # 状态码

使用Requests爬虫

内建模块过于低级, 使用 Requests 更加便捷

pip install requests
import requests

# 服务器反爬虫机制会判断客户端请求头中的User-Agent是否来源于真实浏览器,所以,我们使用Requests经常会指定UA伪装成浏览器发起请求
headers = {'user-agent': 'Mozilla/5.0'}
r1 = requests.get("https://httpbin.org/ip", headers=headers)  # Get请求

print(r1)  # 响应对象
print(r1.content)  # 响应内容
print(r1.status_code)  # 响应码

# POST请求
r2 = requests.post('http://httpbin.org/post', data={'key': 'value'})

requests 支持将参数抽离出来作为方法的参数(params)传递过去

>>> url = "http://httpbin.org/get"
>>> r = requests.get(url, params={"key":"val"})
>>> r.url
u'http://httpbin.org/get?key=val'

指定Cookie

Cookie 是web浏览器登录网站的凭证,虽然 Cookie 也是请求头的一部分,我们可以从中剥离出来,使用 Cookie 参数指定

>>> s = requests.get('http://httpbin.org/cookies', cookies={'from-my': 'browser'})
>>> s.text
u'{\n  "cookies": {\n    "from-my": "browser"\n  }\n}\n'

设置超时时间

r = requests.get('https://google.com', timeout=5)

设置代理

一段时间内发送的请求太多容易被服务器判定为爬虫,所以很多时候我们使用代理IP来伪装客户端的真实IP。

import requests

proxies = {
    'http': 'http://127.0.0.1:1080',
    'https': 'http://127.0.0.1:1080',
}

r = requests.get('http://www.kuaidaili.com/free/', proxies=proxies, timeout=2)

使用 Session

如果想和服务器一直保持登录(会话)状态,而不必每次都指定 cookies,那么可以使用 session,Session 提供的API和 requests 是一样的。

import requests

s = requests.Session()
s.cookies = requests.utils.cookiejar_from_dict({"a": "c"})
r = s.get('http://httpbin.org/cookies')
print(r.text)
# '{"cookies": {"a": "c"}}'

r = s.get('http://httpbin.org/cookies')
print(r.text)
# '{"cookies": {"a": "c"}}'

爬取知乎专栏关注的列表

现在我们使用Requests完成一个爬取知乎专栏用户关注列表的简单爬虫为例,找到任意一个专栏,打开它的关注列表,通过Chrome开发者工具可以找到关注列表的网页地址

python爬虫大数据采集与挖掘电子书 python3网络爬虫数据采集_python爬虫大数据采集与挖掘电子书_04

import json

import requests


class SimpleCrawler:
    init_url = "https://zhuanlan.zhihu.com/api/columns/SVlaw/followers"
    offset = 0

    def crawl(self, params=None):
        # 必须指定UA,否则知乎服务器会判定请求不合法
        headers = {
            "Host": "zhuanlan.zhihu.com",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                          "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
        }
        response = requests.get(self.init_url, headers=headers, params=params)
        print(response.url)
        data = response.json()
        # 分页加载更多,递归调用 这里为了演示只获取前100条数据
        while self.offset < 100:
            self.parse(data)
            self.offset += 20
            params = {"limit": 20, "offset": self.offset}
            self.crawl(params)

    def parse(self, data):
        # 以json格式存储到文件
        with open("followers.json", "a", encoding="utf-8") as f:
            for item in data:
                f.write(json.dumps(item))
                f.write('\n')


if __name__ == '__main__':
    SimpleCrawler().crawl()

参考

本文主要参考: 使用 Requests 实现一个简单网页爬虫