分布式爬虫(二)

高级搜索与爬虫框架

Posted by Remilia Scarlet on March 2, 2020

高级搜索与简单静态爬虫

高级搜索关键字

通过使用高级搜索关键字可以有效限定搜索范围, 进而过滤得到指定的内容. 常用的关键字及对应用法如下:

  • contains:文件后缀 - 确保搜索结果指向包含指定文件后缀的页面.
    • 搜索CODEX破解的单机游戏种子codex contains:torrent
    • 搜索软件压缩包nginx contains:gz
  • ext:后缀 - 确保搜索结果的URL包含指定后缀.
    • 搜索登录界面登录 ext:jsp
  • filetype:文件后缀 - 确保搜索结果是指定后缀的文件.
    • 搜索与人脸对齐有关的论文face alignment filetype:pdf
    • 搜索备案信息表格备案 filetype:xls
  • inanchor:文本 - 锚文本中包含指定文本
  • intitle:文本 - 网页标题包含指定文本
    • 搜索标题中包含后台登录的网站intitle:后台登录
  • inbody:文本 - 网页内容包含指定文本
    • 搜索内容中包含登录的选课网站选课 inbody:登录
  • site:域名 - 确保搜索结果来自于指定域名.
    • 搜索政府发布的某些信息一带一路 site:gov.cn
    • 搜索交通运输部发布的技术规范文件技术规范 site:mot.gov.cn filetype:pdf
    • 搜索教育部政策文档发布页面政策 site:moe.gov.cn contains:docx
  • language:语言代码 - 搜索指定语言的结果.
    • 搜索某些英文教程opencv tutorial language:en
  • ip:点分十进制地址 - 确保搜索结果来自于指定地址, 目前仅支持IPV4.
  • url:指定域 - 检查列出的域或网址是否在必应的索引内.
  • prefer:倾向内容 - 确保搜索结果更倾向于指定内容.
    • 搜索足球信息但更倾向于尤文图斯football prefer:Juventus
  • loc:国家代码 - 确保搜索结果来自指定国家或地区.
    • 搜索中国台湾TVCG期刊投稿信息TVCG loc:tw
    • 搜索中国大陆SIGGRAPH会议投稿信息SIGGRAPH loc:cn

注意: 所有关键字冒号之后都不需要添加空格; extlocurlprefer关键字在中国大陆的使用受到限制.

高级搜索选项

高级搜索选项是常用逻辑运算符的集合, 通过与关键字配合使用可实现更灵活的搜索, 其用法如下:

  • +搜索词 - 强制查找指定搜索词.
    • 搜索冰雪树图片而不是Bing学术图片 +bingxueshu
  • “搜索词” - 搜索时完全匹配指定搜索词.
    • 搜索标题中包含完全匹配内容的结果intitle:"face alignment"
  • () - 优先级分组.
    • 搜索某些网站的并集gaze (site:thecvf.com OR site:arxiv.org)
  • AND& - 查找所有搜索词.
    • 同时搜索某些关键词gaze & face & body site:thecvf.com
  • NOT- - 排除指定搜索词.
    • 屏蔽某些低质量网站的结果python 3.8 -csdn -oschina -zol
  • OR| - 或运算指定搜索词.
    • 查询某些年份的论文inbody:pose (2018 OR 2019) site:arxiv.org

注意: 空格可以代替AND; 除高级搜索选项之外的其他符号如果不被包含在""内, 则在搜索时会被忽略; NOTANDOR在使用时必须大写.

同步爬取静态资源

首先要构造网络请求, 这里我根据使用习惯选择requests库, 当然也可以用urllib或其他模块.

1
2
3
4
5
6
7
8
9
10
11
12
import requests

# 默认User-Agent为python-requests/版本号
# 配置合适的`User-Agent`可以将你的爬虫伪造成浏览器.
response = requests.get("你要爬的URL",
                        headers={"User-Agent": "浏览器标识"},
                        paras={"参数A": "值A", "参数B": "值B"})

# 验证你发送的请求头是什么
print(response.request.headers)
# 可以查看响应头包含的字段
print(response.headers)

得到响应结果之后, 先用lxml模块重构etree, 然后通过XPATHetree中获得需要的数据.

1
2
3
4
5
6
7
from lxml import etree

# 用etree模块重构html树
html = etree.HTML(response.text)
# 获得你需要的数据
article_title = html.xpath('你的XPATH解析规则')
# 其他处理 ...

闭包简单封装发送请求解析结果的业务逻辑. 详细调用方式与解析细节请参见完整代码.

1
2
3
4
5
6
7
8
def spider_builder(*, url_bulider, xpath_rules, **kwargs):

    def spider(content):
        response = requests.get(url_bulider(content), **kwargs)
        html = etree.HTML(response.text)
        return (html.xpath(rule) for rule in xpath_rules)

    return spider

注意: 限制爬取频率可以让你的爬虫更像真实的用户, 防止被目标网站封禁IP地址.

单线程异步并发爬虫

aiohttp

内核级线程就是我们常用的pthread, 他的调度完全取决于内核, 用户级线程就是async..await. 他的调度受用户(程序员)控制,

可以通过队列实现任务的有序处理

爬虫框架

爬虫是能够批量发送网络请求并对返回的数据进行解析与存储的工具. 为了更高效地获取网络中的内容, 在设计爬虫程序时不仅需要通过更换网络代理、伪装User-Agent等方式来应对网站的反爬虫机制, 还需要借助异步IO、分布式等技术手段提升资源的利用率. 常用的爬虫框架会集成上述模块并提供high-level的调用接口, 因此可以显著提升爬虫程序的编写效率. Scrapy就是一个用于批量提取网站结构化数据的应用程序框架, 目前被广泛应用于数据挖掘、历史存档、文本信息处理等领域.

安装与简单应用

本文的测试环境, 注意scrapy 2.0以及之后的版本仅支持python 3:

  • Ubuntu 20.04 LTS
  • python 3.8.2
  • Scrapy 2.1.0
  • scrapy-redis 0.6.8

鉴于国内大部分网络运营商限制了对pypi.org的访问, 因此建议通过替换pip软件源为国内镜像的方式来提升模块下载速度.

1
pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

修改为国内软件源之后, 通过pip直接安装.

1
pip3 install Scrapy scrapy-redis

动态渲染

requests_html

案例1: 批量下载论文

gaze estimation filetype:pdf (site:openaccess.thecvf.com OR site:arxiv.org)

案例2: 表情包爬取

案例3: 视频评论爬取

参考内容