Python 深度学习实战:网络爬虫

发布于:2023-10-25 ⋅ 阅读:(117) ⋅ 点赞:(0)

作者:禅与计算机程序设计艺术

1.背景介绍

网络爬虫(英语:Web crawler,通常缩写为crawler或web crawl),也被称为网页蜘蛛,网络机器人或者自动索引机,是一个可以获取网站上所有可用链接的信息的程序或者脚本。它的基本工作原理就是按照一定的规则,递归地浏览网站上的页面,并提取其中包含的URL地址。通过对这些URL地址的分析、跟踪以及处理,可以汇总得到整个网站上所有页面的信息。由于爬虫属于网络爬虫的一种,因此它也可以用来爬取其他基于网络的数据,如文本数据、图片数据等。网络爬虫具有以下优点:

  • 可以收集大量的互联网信息,包括文本信息、视频信息、音频信息、图片信息等;
  • 对搜索引擎来说非常重要,可以用于数据采集、存储和索引,并形成网站的目录结构;
  • 爬虫可以帮助用户发现网站中的垃圾信息,并进行有效地整理、分类和过滤;
  • 在网络环境不稳定时,爬虫能够保持持续运行,从而保证数据的及时性和完整性。 本文将以“如何用Python实现一个简单的网络爬虫”为题,来阐述网络爬虫的原理、原型设计、编程方法、示例代码以及应用场景。

    2.核心概念与联系

    2.1 网络爬虫与蜘蛛

    网络爬虫(英语:Web crawler,通常缩写为crawler或web crawl),也被称为网页蜘蛛,网络机器人或者自动索引机,是一个可以获取网站上所有可用链接的信息的程序或者脚本。它的基本工作原理就是按照一定的规则,递归地浏览网站上的页面,并提取其中包含的URL地址。通过对这些URL地址的分析、跟踪以及处理,可以汇总得到整个网站上所有页面的信息。由于爬虫属于网络爬虫的一种,因此它也可以用来爬取其他基于网络的数据,如文本数据、图片数据等。

2.2 抓取方式

网络爬虫最基本的抓取方式是“单线程抓取”。指的是只有一个线程在抓取网站资源,这种模式简单易懂,效率高,但是同时只能下载很少的网站内容。如果需要下载的网站内容多,单线程的效率就会受到限制,这时候就要采用分布式爬虫。

分布式爬虫分为以下三种类型:

  • 分布式垂直爬虫:在同一个域名下,通过不同IP进行下载,实现了相同网站内容的不同IP节点的抓取,一般用于大量的静态内容的抓取。
  • 分布式横向爬虫:在多个域名下,通过不同IP进行下载,实现了多个网站内容的抓取,一般用于动态内容的抓取。
  • 反向代理:利用中间服务器,对外隐藏真实IP地址,达到隐藏自身IP、防止被封禁、扩充采集能力的目的。

2.3 数据保存方式

爬取完成后,爬虫会把抓取到的相关数据保存到本地磁盘文件中,主要保存两类数据:

  • HTML源码:保存页面的原始HTML代码,可用于分析网页结构、提取所需信息。
  • 解析数据:经过分析提取后的所需数据,比如,图片、视频、文本等。

2.4 调度策略

爬虫的调度策略有两种:

  • 广度优先:先访问第一层页面,再依次访问第二层页面、第三层页面,直至抵达网站的尾页。
  • 深度优先:先访问网站首页,然后深入其内部,找到其子页面,再继续深入,直至抵达网站的尾页。

深度优先的策略会比广度优先的方式更加细致地爬取网站信息,但是由于每个页面都需要进行一次请求,所以速度可能会比较慢。

3.核心算法原理和具体操作步骤以及数学模型公式详细讲解

3.1 URL

URL,即统一资源定位符,是一个通过Internet传送特定资源的字符串,由一系列字符组成,用来标识一个互联网资源。URL主要由四部分构成:协议、主机名、端口号、路径。其中协议又可分为http、https、ftp等。例如:http://www.baidu.com/s?wd=python

3.2 HTTP协议

HTTP(HyperText Transfer Protocol)即超文本传输协议,是用于从万维网(WWW: World Wide Web)服务器传输超文本到本地浏览器的通信协议。

HTTP协议是建立在TCP/IP协议之上的,默认使用80端口。HTTP协议的请求方式有GET、POST、HEAD、PUT、DELETE等。GET请求用于从服务器取得资源,POST请求用于向服务器发送数据,HEAD请求类似于GET,但只返回HTTP头部信息,而不返回实体的内容。PUT请求用于向指定资源上传其最新内容,DELETE请求用于删除指定的资源。

3.3 网络爬虫原理

网络爬虫是一种通过网页链接进行网页抓取的自动化程序。它是一个程序,需要有一些特殊的技巧才能实现。网络爬虫主要分为四个阶段:

  • 初始抓取阶段:首先向某一网站发起请求,获取该网站的根URL,然后加入到待爬队列。
  • 链接抓取阶段:网络爬虫从待爬队列中选择一个URL,发送HTTP请求,获取该URL的响应内容。然后解析该响应内容中的链接,并将新链接加入待爬队列。
  • 下载页面阶段:网络爬虫从待爬队列中选择一个URL,发送HTTP请求,获取该URL的响应内容,并将其存储到硬盘文件中。
  • 数据分析阶段:网络爬虫读取硬盘文件中的页面内容,对其进行分析,提取出有用的信息,如关键字、URL、摘要、标签等。

3.4 请求库urllib

Python提供了urllib模块来支持网络请求。如下面的代码所示:

import urllib.request
response = urllib.request.urlopen('http://www.baidu.com')
html_data = response.read()
print(html_data)

urllib.request.urlopen()方法用来打开一个URL,并且返回一个HTTPResponse对象。这个对象有一个read()方法用来读取服务器的响应数据,也就是HTML源码。

3.5 Beautiful Soup库

Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库。我们可以使用requests库来获取HTML源码,然后通过BeautifulSoup库解析HTML。以下的代码演示了一个简单的例子:

import requests
from bs4 import BeautifulSoup

url = 'https://www.example.com'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')

title = soup.find('h1').text
paragraphs = [p.text for p in soup.find_all('p')]

print("Title:", title)
for i, paragraph in enumerate(paragraphs):
    print("{}:".format(i+1), paragraph)

上面代码中的requests库用来获取HTML源码,BeautifulSoup库用来解析HTML源码。通过find()方法查找

标签的文本内容,通过find_all()方法查找所有

标签的文本内容。

3.6 智能爬虫

智能爬虫(intelligent spider or web robot)是一种具有一定智能、自动化功能的网络爬虫,它能够自动识别并抓取网站上符合条件的网页信息,包括文章、图片、视频、文件等。智能爬虫具备如下功能:

  • 网页抓取:通过智能的网页抓取技术,智能爬虫可以批量、快速抓取网站上的网页信息;
  • 网页索引:智能爬虫可以自动生成索引,帮助用户快速检索感兴趣的网页;
  • 数据分析:智能爬虫可以对抓取到的数据进行分析,对网站运营状况、市场流量、品牌影响力等进行实时的监测;
  • 数据采集:智能爬虫可以定期抓取网站数据,将其保存到数据库或文件系统中,用于后期的数据分析和报告。

3.7 反爬虫机制

反爬虫机制(anti-spidering mechanisms)是一种预防网络蜘蛛行为的方法,旨在保护网站不被网络蜘蛛等恶意爬虫侵犯。目前,主流的反爬虫机制有验证码、IP封锁、加密压缩等。

  1. IP封锁

    IP封锁是最常用的反爬虫机制。当检测到一段时间内某个IP地址的请求量太多,超过了正常的访问流量,就认为可能是网络蜘蛛,并封锁该IP地址。比如:电信运营商对于同一IP的访问流量超过了一定的阈值之后会进行封锁。

    通过使用云服务器(云解析服务)来动态切换IP,可以有效缓解此问题。另外,还可以通过设置超时时间和访问频率来限制爬虫的请求速率,也可以降低触发封锁的风险。

  2. 验证码

    很多网站为了保障用户的网络安全,都会设置验证码,即用户需要输入验证码才能登录或注册。然而,设置了验证码之后,反爬虫攻击的成功率显著下降。因为爬虫程序往往会模拟真实的浏览器行为,造成人工识别困难。

    有些网站为了绕过验证码,会通过各种手段欺骗爬虫程序,比如:生成假的验证码图案、伪造响应头信息、使用拼音、错别字等。通过分析爬虫程序的行为,可以发现是否存在这些攻击行为,并根据攻击行为采取相应的应对措施,比如:增加验证码识别难度、封禁IP地址、强制修改用户设置等。

  3. 加密压缩

    使用HTTPS加密通讯,可以有效减轻中间人攻击和篡改数据等风险。通过压缩算法和混淆技术来保护数据的隐私。然而,压缩算法使用的参数较小,无法彻底干扰爬虫程序的正常运行。

    此外,还有一些爬虫程序会窃取其他网站的敏感数据,比如:身份证号码、银行卡号、手机号码、邮箱账号密码等。通过设置不同的User-Agent,可以使爬虫程序认为自己是合法的浏览器,从而避开这些爬虫程序的侦察。

  4. 设备标识符

    有些网站为了防范盗版,会将访客的设备标识符携带在HTTP请求头中,服务器根据设备标识符来区分普通用户和盗版用户。虽然设备标识符可以唯一标识用户设备,但是设备标识符也是可以伪造的,因此可以用来对抗反爬虫机制。

    有些网站为了绕过设备标识符,会使用cookie来记录用户的访问历史、身份验证信息等。由于cookie存在于本地,可以被网页JavaScript等恶意代码读取,因此也可以用来对抗反爬虫机制。

    可以通过设置无痕模式(ghost mode)来躲避设备标识符,这是一种不可靠的做法,但是可以有效阻止部分爬虫程序的侦察。

4.具体代码实例和详细解释说明

下面我们结合以上知识点,用Python实现一个简单的网络爬虫。

4.1 需求

  • 每页显示10条帖子
  • 记录每条帖子的标题、链接、作者、时间、回复数量等信息
  • 将爬取结果保存到csv文件中
  • 需要用多进程来实现爬取效率
  • 可选:在控制台输出当前进度

4.2 步骤

  1. 导入必要的库

    import csv 
    import time
    from multiprocessing import Pool
    import requests
    from bs4 import BeautifulSoup
  2. 设置请求头

    headers={
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Connection": "keep-alive",
        "Cookie":"your cookie here",
        "Host": "tieba.baidu.com",
        "Referer": "https://tieba.baidu.com/",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
    }

    上面代码中,headers字典设置了请求头信息。User-Agent字段是浏览器标识,可以更改为你的浏览器标识。

  3. 创建csv文件

    with open('tieba.csv', 'w', encoding='utf-8', newline='') as f:
         writer = csv.writer(f)
         header = ['标题', '链接', '作者', '时间', '回复数量']
         writer.writerow(header)

    上面代码中,创建了名为tieba.csv的csv文件,写入表头信息。

  4. 定义函数

    • 获取页面内容
      def get_page(url):
          try:
              r = requests.get(url, headers=headers, timeout=5)
              if r.status_code == 200:
                  return r.content.decode('utf-8')
          except Exception as e:
              print(e)
      get_page()函数接受URL作为输入参数,发送HTTP请求,获取响应内容,并返回。
    • 提取信息
      def parse_info(html):
          soup = BeautifulSoup(html, 'html.parser')
          items = []
          for item in soup.select('.threadlist_title'):
              link = 'https:' + item.a['href'][2:] # remove /p/ prefix
              author = item.find(class_='username').string
              title = item.find(class_='j_th_tit').string
              info = ''.join([x.strip()+'\n' for x in item.find(class_="threadlist_lastpost").stripped_strings]) # post time and reply count
              data = [link, title, author] + info.split('\n')[::-1][:4][::-1] # reverse order of list elements
              items.append(data)
          return items
      parse_info()函数接收页面内容作为输入参数,提取出每条帖子的标题、链接、作者、时间、回复数量等信息,并将信息保存到列表中返回。
    • 保存数据
      def save_data(items):
          global total
          with open('tieba.csv', 'a+', encoding='utf-8', newline='') as f:
             writer = csv.writer(f)
             for item in items:
                 writer.writerow(item)
                 total += len(item)
                 show_progress(total)
      save_data()函数接收提取出的列表作为输入参数,写入到tieba.csv文件中。show_progress()函数用来显示当前进度。
    • 模板页面
      page = 1
      url = 'https://tieba.baidu.com/'
      while True:
          start = (page-1)*50 # starting index
          html = get_page('{}?pn={}'.format(url,start))
          if not html:
              break
          items = parse_info(html)
          save_data(items)
          page += 1
          time.sleep(1) # wait for a second between requests
      最后,通过循环获取页面内容、提取信息、保存数据,直到没有更多的页面为止。
  5. 执行程序

    if __name__ == '__main__':
        pool = Pool(processes=4) # set number of processes to 4
        pool.apply_async(template_func(), ())
        pool.close()
        pool.join()

    最后,调用pool对象的apply_async()方法启动多进程,传入一个空元组()表示不需要传递任何参数。

5.未来发展趋势与挑战

网络爬虫作为一种有着广泛的应用领域,拥有丰富的研究和开发方向。以下几方面正在吸引着网络爬虫的研究和开发者:

  • 数据增强:网络爬虫数据增强方法一直在探索中,试图从无监督、半监督甚至有监督学习角度,提升网络爬虫的质量、效率及效果。
  • 用户代理:网络爬虫将面临更多用户代理的挑战。大部分网站为了防止网络蜘蛛进行盗链,都会要求提交用户代理标识,否则就无法获取网页源代码。
  • 浏览器插件:越来越多的浏览器插件正在开发,它们可以提供更多的便利功能给网站的管理员,让管理和使用网站变得更容易。
  • 大规模分布式爬虫:已经出现了一些大规模分布式爬虫项目,如Scrapy Cluster,它通过集群化的方式来提升网络爬虫性能。
  • 概念理解能力:虽然网络爬虫已经成为热门话题,但对于初学者来说,掌握网络爬虫的基本概念、原理和术语还是一项重要的技能。

6.附录常见问题与解答

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到