说明

  1. 学习参考视频【Python+爬虫】爆肝两个月!拜托三连了!这绝对是全B站最用心(没有之一)的Python+爬虫公开课程,从入门到(不)入狱 !_哔哩哔哩_bilibili
  2. 笔记并不涵盖此系列视频中的python教学部分和html介绍部分,主要学习了Requests和BeautifulSoup库的简单使用方式(用代码和实际案例学习基本设计思路已经基本用法)
  3. 并未对相关代码做过多说明,可以结合上方链接中的视频进行实操和理解

概览

可刑的注意事项

爬虫玩的好,牢饭吃的早,越学越有判头

红线

  • 爬取公民隐私数据
  • 爬取受著作权保护的内容
  • 爬取国家事务、国防建设、尖端科学技术领域的计算机系统
  • ……

温和善良虫的特点

  1. 请求数量和频率不能过高,否则就无异于DDoS攻击

    DDoS攻击就是给服务器发送海量高频请求,让网站资源被耗尽,无法服务其他正常用户

  2. 如果网站做了明显的反爬限制(如登录,验证码等)不要强行突破

  3. 查看网站的robots.txt文件,了解可爬取的网站路径范围,该文件会指明哪些网站可爬,哪些不可爬,有些还会专门列出针对搜索引擎爬虫的许可范围

步骤及需学技术

1. 获取网页内容

  • http请求:通过发送HTTP请求获取网页内容
  • Python的Requests库:通过它就可以用python代码简单优雅地发送HTTP请求

2. 解析网页内容

  • HTML网页结构:获得的网页内容通常是HTML格式
  • Python的Beautiful Soup库:帮助我们解析获取到的HTML内容

3. 储存或分析数据

HTTP请求

简介

  • HTTPHypertext Transfer Protocol,超文本传输协议
  • 一种在客户端和服务器之间的请求-响应协议

请求方法

GET方法

  • 获得数据
    • 例如,点入一个网页,就会发送GET请求获取到网页内容
  • 爬虫常用GET方法

POST方法

  • 创建数据
    • 例如,提交账号注册表单时,发送POST请求,把相关信息放到请求主体里,传给服务器

HTTP请求实例

1
2
3
4
5
6
7
POST/user/info HTTP/1.1                        请求行
Host: www.example.com 请求头
User-Agent: curl/7.77.0
Accept: */*

{"username":"vks" 请求体
"email":"vkswhu@outlook.com"}

HTTP请求结构

请求行

POST/user/info HTTP/1.1
POST/user/info?new_user=true HTTP/1.1

  • 请求类型"POST"

  • 资源路径"user/info "

    • 指明了要访问服务器的哪个资源
    • 例:”.www.douban.coms/movie/top250
      • movie/top250:资源路径
      • 第一个斜杠表示资源路径的根
      • 根后的movie/top250就是要访问的资源的路径
  • 查询参数:”.www.douban.com/movie/top250?start=75&filter=unwatched

    • start=75&filter=unwatched 为查询参数
    • 可以传递给服务器额外的信息,不同信息之间用’&’分隔
  • 协议版本HTTP/1.1

    • 指HTTP协议的版本

请求头

1
2
3
Host: www.example.com                          请求头
User-Agent: curl/7.77.0
Accept: */*
  • 包含一些给服务器的信息

  • Host:指主机域名,主机域名结合请求行的路径资源,可以得到一个完整的网址

  • User-Agent:用来告知服务器 客户端的相关信息

  • Accept:告知服务器 客户端想要接受的响应数据是什么类型的

    • 接收HTML:text/html
    • 接收JSON:application/json
    • 接受HTML和JSON:text/html,application/json
    • 接收任意类型:* / *
    • 接收多种类型可用逗号分隔,如上例text/html,application/json

请求体

  • 客户端传给服务器的其他任意数据(GET方法请求体一般为空)

HTTP响应

  • 在服务器接受到HTTP请求后,会根据所有这些信息,返回HTTP响应

HTTP响应实例

1
2
3
4
5
6
7
8
HTTP/1.1 200 OK                            状态行
Date: Fri, 27 Jan 2023 02:10:48 GMT 响应头
Content-Type: text/html;charset=utf-8

<!DOCTYPE html> 响应体
<head><title>首页<title></head>
<body><h1>Vcats</h1><p>hi!</p></body>
</html>

HTTP响应结构

状态行

HTTP/1.1 200 OK

  • 协议版本HTTP/1.1
  • 状态码200
  • 状态消息OK

状态码和状态消息是对应的,常见的状态码和状态消息如下:

  • 200 OK:客户端请求成功
  • 301 Moved Permanently:资源被永久移动到新地址
  • 400 Bad Request:客户端不能被服务器所理解
  • 401 Unauthorized:请求未经授权
  • 403 Forbidden:服务器拒绝提供服务
  • 404 Not Found:请求资源不存在
  • 500 Internal Server Error:服务器发生不可预期错误
  • 503 Server Unavailable:服务器当前不能处理客户端的请求

响应头

1
2
Date: Fri, 27 Jan 2023 02:10:48 GMT        响应头
Content-Type: text/html;charset=utf-8

包含一些告知客户端的信息

  • Date:生成相应的日期和时间
  • Content-Type:返回内容的类型及编码格式
    • 例如上例为:响应类型是HTML,编码是UTF-8

响应体

1
2
3
4
<!DOCTYPE html>                            响应体
<head><title>首页<title></head>
<body><h1>Vcats</h1><p>hi!</p></body>
</html>

服务器想给客户端的内容

  • 如本例返回的内容类型是HTML,响应体就是HTML

Python的Request库

安装

  • 命令pip install requests

使用实例

1
2
3
4
5
6
7
import requests

response = requests.get("http://books.toscrape.com/")
if response.ok:
print(response.text)
else:
print("请求失败")

get in Requests

  • 在使用Requests 库的函数发送请求时,请求头的内容会自动被生成,无需手动传入
  • 如果向指定某些信息进行更改,可以额外传入名为headers的参数,其数据类型为字典,里面的各个键值对对应了我们要传入的各个信息
    • 作用:1. 把爬虫程序伪装成正常的浏览器
    • 获取伪装header方法:用浏览器进入任意一个网页,打开“检查”,进入network,然后刷新网页,就可以看到浏览器发送的http请求,点击任意请求并找到其中的Request Headers,找到User-Agent,把冒号后的信息复制下来即可
      1
      2
      3
      4
      5
      6
      7
      8
      import requests

      head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) }
      response = requests.get("http://books.toscrape.com/", header = head)
      if response.ok:
      print(response.text)
      else:
      print("请求失败")

Beautiful Soup

BeautifulSoup将网页html解析成树状结构

安装

指令pip install bs4

使用

  • 获取所有书的价格

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from bs4 import BeautifulSoup  
    import requests
    content = requests.get("http://books.toscrape.com/").text
    #传入要解析的对象,指定HTML解析器
    soup = BeautifulSoup(content, "html.parser")
    #findAll能根据标签、属性等 找到所有符合的元素
    all_prices = soup.findAll("p", attrs = {"class": "price_color"})
    #第一个参数传p,表示找所有<p>标签
    #第二个参数attrs(可选),赋值为一个字典,键值对就对应想找的属性和值
    for price in all_prices:
    print(price.string) #string属性会把标签包围的文字返回给我们
  • 获取所有书的书名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from bs4 import BeautifulSoup  
    import requests
    content = requests.get("http://books.toscrape.com/").text
    soup = BeautifulSoup(content, "html.parser")
    all_titles = soup.findAll("h3")
    for title in all_titles:
    link = title.find("a")
    #find返回的不是可迭代对象,直接是第一个对象
    print(link.string)
  • 获取豆瓣top250电影标题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import requests  
    from bs4 import BeautifulSoup

    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0"}

    for start_num in range(0, 250, 25):
    response = requests.get(f"https://movie.douban.com/top250?start={start_num}", headers = headers)
    html = response.text
    soup = BeautifulSoup(html, "html.parser")
    all_titles = soup.findAll("span", attrs={"class": "title"})
    for title in all_titles:
    title_string = title.string
    if "/" not in title_string:
    print(title_string)

后续进阶

正则表达式

  • Python正则表达式库:re
  • 作用:在解析内容时,通过更加精简的代码,根据自定义规则匹配一个或多个目标字符

多线程

  • Python多线程库:threading
  • 作用:不同线程同时爬取多个页面,增加爬虫程序的效率,缩短爬取大量网页所花费的时间

数据库

  • 作用:存储爬取的数据

数据分析

  • 作用:分析爬取的数据