爬虫是什么?

爬虫是一种自动化程式,用于自动爬取网络上的讯息,被爬取的目标大多是网页

爬虫能做什么?

当然是自动化的爬取网页上的内容,这些内容可以是图片、文字
具体的使用例就比如 pixiv 爬虫,可以自动化的帮助我们爬取今日的 R18 排行榜

开始

因为是最简单的网页爬虫,所以我们这里选择使用 Python 开发。Python 拥有大量便于爬虫开发的库,可以十分方便的发起HTTP请求并使用正则过滤。

如果阁下不了解Python是什么,请详见Python官网: python.org

创建文件

创建一个空白目录,在目录中创建一个 .py 文件,并导入我们这次需要使用的两个库: requests re

  • requests 方便的发起 HTTP 请求
  • re 使用正则表达式过滤文字
1
import requests, re

选定目标

我们爬取的目标选择 HK01 的新闻

  • 新闻标题
  • 撰文人
  • 内容和图片

示例

模拟浏览器发起 HTTP 请求

大部分网站的反爬机制都不会很严格,我们只需要添加用户代理头就可以通过验证(如果有其他验证,请尝试添加其他常见请求头)

  • 这里我们只添加 user-agent
    • user-agent 可以翻译为用户代理,表明用户使用的浏览器版本,装置设备等信息
1
2
3
4
5
6
7
8
9
10
11
import requests, re

header = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.78"
}

# 发起 Get 请求并取 text(html)
html = requests.get("https://www.hk01.com/%E7%AA%81%E7%99%BC/669730/%E9%A6%AC%E6%96%99%E6%B0%B4%E5%BE%80%E6%9D%B1%E5%B9%B3%E6%B4%B2%E6%B8%A1%E8%BC%AA%E5%86%92%E7%85%99-320%E4%B9%98%E5%AE%A2%E5%8F%8A%E8%88%B9%E5%93%A1%E9%A0%86%E5%88%A9%E7%96%8F%E6%95%A3").text

# 输出刚刚请求到的内容
print(html)

如果这里一切正常的话,运行程式应该可以看到这个页面的html原始码

过滤html

下一步是从请求到的HTML原始码内得到我们想要得到的内容,这个时候就用到了 re 库(正则匹配)

我们可以使用开发人员工具(在浏览器点击 F12 打开)来阅读这个页面的HTML原始码,来编写匹配使用的正则表达式

示例

发现这里的内容有固定的id名和标签名,我们就可以按这个特征来写正则表达式

1
2
3
title = re.compile(r'<h1 id=\"articleTitle\"([\s\S]*?)>([\s\S]*?)\<\/h1\>').findall(html)

print(title)

输出:

1
[(' data-author="朱雅霜" data-category="突發" data-type="article" class="text-2xl md:text-2.5xl mb-3 md:mb-4 font-semibold text-black-78"', '馬料水往東平洲渡輪冒煙\u3000320乘客及船員順利疏散')]

这里输出的内容是一个列表套着一个元组,代表有一个匹配项和两个子匹配项,第二个子匹配项是我们需要的标题

1
2
# 可以使用下标的方式取出内容(这里的\u3000320是unicode码)
print(title[0][1])

输出:

1
馬料水往東平洲渡輪冒煙 320乘客及船員順利疏散

完成

按这个方法完成所有的内容,并输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import requests, re

# 伪造的 HTTP 请求头
header = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.78"
}

# 发起 Get 请求并取 text(html)
html = requests.get("https://www.hk01.com/%E7%AA%81%E7%99%BC/669730/%E9%A6%AC%E6%96%99%E6%B0%B4%E5%BE%80%E6%9D%B1%E5%B9%B3%E6%B4%B2%E6%B8%A1%E8%BC%AA%E5%86%92%E7%85%99-320%E4%B9%98%E5%AE%A2%E5%8F%8A%E8%88%B9%E5%93%A1%E9%A0%86%E5%88%A9%E7%96%8F%E6%95%A3").text

# 正则匹配标题
title = re.compile(r'<h1 id=\"articleTitle\"([\s\S]*?)>([\s\S]*?)\<\/h1\>').findall(html)
# 正则匹配撰稿人
author = re.compile(r'<div class=\"text-sm leading-6 text-black-40 mb-0.5 flex flex-row md:pb-0.75\"><span class=\"flex whitespace-nowrap\">撰文:<\/span><span class=\"flex\">([\s\S]*?)<\/span><\/div>').findall(html)
# 正则匹配正文内容
text = re.compile(r'<article id=\"article-content-section\" class="cmp-article-detail">([\s\S]*?)<\/article>').findall(html)[0]
# 取所有html tag
tag = re.compile(r'<([\s\S]*?)>').findall(text)
# 循环替换为空
for i in tag:
text = text.replace("<"+i+">", "")

print(title[0][1])
print(author[0])
print(text)

输出:

1
2
3
4
馬料水往東平洲渡輪冒煙 320乘客及船員順利疏散
朱雅霜 楊嘉朗
今(29日)早10時許,一艘載320人的翠華船務渡輪,由馬料水開往東平洲,航行途中冒出濃煙。消防趕往現場,開喉為船隻降溫,翠華船務派出另一艘渡輪到場,在消防及水警協助下「船過船」疏散。上午11時37分,火警升為二級。船上318名乘客及2名船員全數順利登
上另一艘渡輪,其後抵達東平洲,事故中無人受傷。一艘由馬料水開往東平洲的渡輪於途中冒煙,船上逾300人需疏散。(楊嘉朗攝)01新聞

图片因为懒得写所以没写