准备部分

0x01 爬虫的简介和价值

a. 简介

自动抓取互联网数据的程序,是基础技术之一

b. 价值

快速提取网络中有价值的信息

0x02 爬虫的开发环境

a. 环境清单

  1. Python3.7
  2. 开发环境:Mac、Windows、Linux
  3. 编辑器:Pycharm
  4. 网页下载:requests(2.21.0)
  5. 网页解析:BeautifulSoup/bs4(4.11.2)
  6. 动态网页下载:Selenium(3.141.0)

b. 环境测试

  1. 新建一个 Python 软件包,命名为 test

  2. 在上述软件包中新建一个 Python 文件,命名为 test_env

  3. 测试代码如下

    import requests
    from bs4 import BeautifulSoup
    import selenium print("OK!")

    如果成功输入OK!则说明测模块安装成功


基础部分

0x03 简单的爬虫架构和执行流程

  1. 爬虫调度端(启动、停止)

  2. 爬虫架构(三大模块)

    graph LR
    A(URL 管理器)--URL-->B(网页下载器)
    B--HTML-->C(网页解析器)
    C-.URL.->A
    1. URL 管理器

      URL 对管理,防止重复爬取

    2. 网页下载器

      网页内容下载

    3. 网页解析器

      提取价值数据,提取新的待爬 URL

  3. 价值数据

0x04 URL 管理器

a. 介绍

  1. 作用:对爬取的 URL 进行管理,防止重复和循环爬取
  2. 对外接口
    • 取出一个待爬取的 URL
    • 新增待爬取的 URL
  3. 实现逻辑
    • 取出时状态变成已爬取
    • 新增时判断是否已存在
  4. 数据存储
    • Python 内存

      • 待爬取 URL 集合:set
      • 已爬取 URL 集合:set
    • redis
      • 待爬取 URL 集合:set
      • 已爬取 URL 集合:set
    • MySQL
      • urls(url, is_crawled)

b. 代码实现

  1. 新建一个 Python 软件包,命名为 utils

  2. 在上述软件包中新建一个 Python 文件,命名为 url_manager

  3. 由于需要对外暴露接口,需要封装成类,代码如下:

    class UrlManager():
    """
    url 管理器
    """ # 初始化函数
    def __init__(self):
    self.new_urls = set()
    self.old_urls = set() # 新增 URL
    def add_new_url(self, url):
    # 判空
    if url is None or len(url) == 0:
    return
    # 判重
    if url is self.new_urls or url in self.old_urls:
    return
    # 添加
    self.new_urls.add(url) # 批量添加 URL
    def add_new_urls(self, urls):
    if urls is None or len(urls) == 0:
    return
    for url in urls:
    self.add_new_url(url) # 获取一个新的待爬取 URL
    def get_url(self):
    if self.has_new_url():
    url = self.new_urls.pop()
    self.old_urls.add(url)
    return url
    else:
    return None # 判断是否有新的待爬取的 URL
    def has_new_url(self):
    return len(self.new_urls) > 0 # 测试代码
    if __name__ == "__main__":
    url_manager = UrlManager() # URL 添加测试
    url_manager.add_new_url("url1")
    url_manager.add_new_urls(["url1", "url2"])
    print(url_manager.new_urls, url_manager.old_urls) # URL 获取测试
    print("=" * 20) # 分割线
    new_url = url_manager.get_url()
    print(url_manager.new_urls, url_manager.old_urls) print("=" * 20)
    new_url = url_manager.get_url()
    print(url_manager.new_urls, url_manager.old_urls) print("=" * 20)
    print(url_manager.has_new_url())

0x05 网页下载器(requests)

a. 介绍

  1. 网址:python-requests

  2. 安装:pip install requests

  3. 介绍:

    Requests is an elegant and simple HTTP library for Python, built for human beings.

    Requests 是一个优雅的、简单的 Python HTTP 库,常常用于爬虫中对网页内容的下载

  4. 执行流程

    graph LR
    A(Python程序<br/>requests 库)--request-->B(网页服务器)
    B--respone-->A

b. 发送 request 请求

request.get/post(url, params, data, headers, timeout, verify, allow_redirects, cookies)

  • url:要下载的目标网页的 URL

  • params:字典形式,设置 URL 后面的参数,如:?id=123&name=xxx

  • data:字典或者字符串,一般用于使用 POST 方法时提交数据

  • headers:设置user-agentrefer等请求头

  • timeout:超时时间,单位是秒

  • verify:布尔值,是否进行 HTTPS 证书认证,默认 True,需要自己设置证书地址

  • allow_redirects:布尔值,是否让 requests 做重定向处理,默认 True

  • cookies:附带本地的 cookies 数据

    urldataheaderstimeout为常用参数

c. 接收 response 响应

res = requests.get/post(url)

  • res.status_code:查看状态码

  • res.encoding:查看当前编码以及变更编码

    (requests 会根据请求头推测编码,推测失败则采用ISO-8859-1进行编码)

  • res.text:查看返回的网页内容

  • res.headers:查看返回的 HTTP 的 Headers

  • res.url:查看实际访问的 URL

  • res.content:以字节的方式返回内容,比如下载图片时

  • res.cookies:服务端要写入本地的 cookies 数据

d. 使用演示

在 cmd 中安装 ipython,命令为:python -m pip install ipython

在 cmd 中启动 ipython,命令为:ipython

In [1]: import requests
In [2]: url = "https://www.cnblogs.com/SRIGT"
In [3]: res = requests.get(url)
In [4]: res.status_code
Out[4]: 200
In [5]: res.encoding
Out[5]: 'utf-8'
In [6]: res.url
Out[6]: 'https://www.cnblogs.com/SRIGT'

0x06 网页解析器(BeautifulSoup)

a. 介绍

  1. 网址:Beautiful Soup: We called him Tortoise because he taught us.

  2. 安装:pip install beautifulsoup4

  3. 介绍:Python 第三方库,用于从 HTML 中提取数据

  4. 使用:import bs4from bs4 import BeautifulSoup

b. 语法

graph LR
HTML网页-->A(创建 BeautifulSoup 对象)
A-->B(搜索节点<br/>find_all, find)
B-.->B1(按节点名称)
B-.->B2(按节点属性值)
B-.->B3(按节点文字)
B-->C(访问节点<br/>名称, 属性, 文字)
  1. 创建 BeautifulSoup 对象

    from bs4 import BeautifulSoup
    
    # 根据 HTML 网页字符串创建 BeautifulSoup 对象
    soup = BeautifulSoup(
    html_doc, # HTML 文档字符串
    'html.parser', # HTML 解析器
    from_encoding = 'utf-8' # HTML 文档的编码
    )
  2. 搜索节点

    # find_all(name, attrs, string)
    # 查找所有标签为 a 的节点
    soup.find_all('a') # 查找所有标签为 a,链接符合 /xxx/index.html 形式的节点
    soup.find_all('a', href='/xxx/index.html') # 查找所有标签为 div,class 为 abc,文字为 python 的节点
    soup.find_all('div', class_='abc', string='python')
  3. 访问节点信息

    # 得到节点: <a href='1.html'>Python</a>
    # 获取查找到的节点的标签名称
    node.name
    # 获取查找到的 a 节点的 href 属性
    node['href']
    # 获取查找到的 a 节点的链接文字
    node.get_text()

c. 使用演示

  • 目标网页

    <html>
    <head>
    <meta charset="utf-8">
    <title>页面标题</title>
    </head>
    <body>
    <h1>标题一</h1>
    <h2>标题二</h2>
    <h3>标题一</h3>
    <h4>标题一</h4>
    <div id="content" class="default">
    <p>段落</p>
    <a href="http://www.baidu.com">百度</a>
    <a href="http://www.cnblogs.com/SRIGT">我的博客</a>
    </div>
    </body>
    </html>
  • 测试代码

    from bs4 import BeautifulSoup
    
    with open("./test.html", 'r', encoding='utf-8') as fin:
    html_doc = fin.read() soup = BeautifulSoup(html_doc, "html.parser")
    div_node = soup.find("div", id="content")
    print(div_node)
    print() links = div_node.find_all("a")
    for link in links:
    print(link.name, link["href"], link.get_text()) img = div_node.find("img")
    print(img["src"])

实战部分

0x07 简单案例

url = "http://www.crazyant.net/"

import requests
r = requests.get(url)
if r.status_code != 200:
raise Exception() html_doc = r.text from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, "html.parser") h2_nodes = soup.find_all("h2", class_="entry-title") for h2_node in h2_nodes:
link = h2_node.find("a")
print(link["href"], link.get_text())

0x08 爬取所有博客页面

  1. requests 请求时附带 cookie 字典

    import requests
    cookies = {
    "captchaKey": "14a54079a1",
    "captchaExpire": "1548852352"
    }
    r = requests.get(
    "http://url",
    cookies = cookies
    )
  2. 正则表达式实现模糊匹配

    url1 = "http://www.crazyant.net/123.html"
    url2 = "http://www.crazyant.net/123.html#comments"
    url3 = "http://www.baidu.com" import re
    pattern = r'^http://www.crazyant.net/\d+.html$' print(re.match(pattern, url1))
    print(re.match(pattern, url2))
    print(re.match(pattern, url3))
  3. 全页面爬取

    from utils import url_manager
    from bs4 import BeautifulSoup
    import requests
    import re root_url = "http://www.crazyant.net" urls = url_manager.UrlManager()
    urls.add_new_url(root_url) file = open("craw_all_pages.txt", "w")
    while urls.has_new_url():
    curr_url = urls.get_url()
    r = requests.get(curr_url, timeout=3)
    if r.status_code != 200:
    print("error, return status_code is not 200", curr_url)
    continue
    soup = BeautifulSoup(r.text, "html.parser")
    title = soup.title.string file.write("%s\t%s\n" % (curr_url, title))
    file.flush()
    print("success: %s, %s, %d" % (curr_url, title, len(urls.new_urls))) links = soup.find_all("a")
    for link in links:
    href = link.get("href")
    if href is None:
    continue
    pattern = r'^http://www.crazyant.net/\d+.html$'
    if re.match(pattern, href):
    urls.add_new_url(href) file.close()

0x09 爬取豆瓣电影Top250

目前该榜单设置了反爬

步骤:

  1. 使用 requests 爬取网页
  2. 使用 BeautifulSoup 实现数据解析
  3. 借助 pandas 将数据写到 Excel
  1. 调用

    import requests
    from bs4 import BeautifulSoup
    import pandas as pd
  2. 下载共 10 个页面的 HTML

    # 构造分页数字列表
    page_indexs = range(0, 250, 25)
    list(page_indexs) def download_all_htmls():
    """
    下载所有列表页面的 HTML,用于后续的分析
    """
    htmls = []
    for idx in page_indexs:
    url = f"https://movie.douban.com/top250?start={idx}&filter="
    print("craw html: ", url)
    r = requests.get(url)
    if r.status_code != 200:
    raise Exception("error")
    htmls.append(r.text)
    return htmls # 执行爬取
    htmls = download_all_htmls()
  3. 解析 HTML 得到数据

    def parse_single_html(html):
    """
    解析单个 HTML,得到数据
    @return list({"link", "title", [label]})
    """
    soup = BeautifulSoup(html, 'html.parser')
    article_items = (
    soup.find("div", class_="article")
    .find("ol", class_="grid_view")
    .find_all("div", class_="item")
    )
    datas = []
    for article_item in article_items:
    rank = article_item.find("div", class_="pic").find("em").get_text()
    info = article_item.find("div", class_="info")
    title = info.find("div", class_="hd").find("span", class_="title").get_text()
    stars = (
    info.find("div", class_="bd")
    .find("div", class_="star")
    .find_all("span")
    )
    rating_star = stars[0]["class"][0]
    rating_num = stars[1].get_text()
    comments = stars[3].get_text() datas.append({
    "rank": rank,
    "title": title,
    "rating_star": rating_star.replace("rating", "").replace("-t", ""),
    "rating_num": rating_num,
    "comments": comments.replace("人评价", "")
    })
    return datas pprint.pprint(parse_single_html(htmls[0])) all_datas = []
    for html in htmls:
    all_datas.extend(parse_single_html(html)) print(all_datas)
  4. 将结果存入 Excel

    df = pd.DataFrame(all_datas)
    df.to_excel("TOP250.xlsx")

End

Python 爬虫初探的更多相关文章

  1. Python爬虫初探 - selenium+beautifulsoup4+chromedriver爬取需要登录的网页信息

    目标 之前的自动答复机器人需要从一个内部网页上获取的消息用于回复一些问题,但是没有对应的查询api,于是想到了用脚本模拟浏览器访问网站爬取内容返回给用户.详细介绍了第一次探索python爬虫的坑. 准 ...

  2. Python爬虫系列 - 初探:爬取旅游评论

    Python爬虫目前是基于requests包,下面是该包的文档,查一些资料还是比较方便. http://docs.python-requests.org/en/master/ POST发送内容格式 爬 ...

  3. 我的第一个 python 爬虫脚本

    #!/usr/bin/env python# coding=utf-8import urllib2from bs4 import BeautifulSoup #res = urllib.urlopen ...

  4. Scrapy框架爬虫初探——中关村在线手机参数数据爬取

    关于Scrapy如何安装部署的文章已经相当多了,但是网上实战的例子还不是很多,近来正好在学习该爬虫框架,就简单写了个Spider Demo来实践.作为硬件数码控,我选择了经常光顾的中关村在线的手机页面 ...

  5. Python 爬虫模拟登陆知乎

    在之前写过一篇使用python爬虫爬取电影天堂资源的博客,重点是如何解析页面和提高爬虫的效率.由于电影天堂上的资源获取权限是所有人都一样的,所以不需要进行登录验证操作,写完那篇文章后又花了些时间研究了 ...

  6. python爬虫成长之路(一):抓取证券之星的股票数据

    获取数据是数据分析中必不可少的一部分,而网络爬虫是是获取数据的一个重要渠道之一.鉴于此,我拾起了Python这把利器,开启了网络爬虫之路. 本篇使用的版本为python3.5,意在抓取证券之星上当天所 ...

  7. python爬虫学习(7) —— 爬取你的AC代码

    上一篇文章中,我们介绍了python爬虫利器--requests,并且拿HDU做了小测试. 这篇文章,我们来爬取一下自己AC的代码. 1 确定ac代码对应的页面 如下图所示,我们一般情况可以通过该顺序 ...

  8. python爬虫学习(6) —— 神器 Requests

    Requests 是使用 Apache2 Licensed 许可证的 HTTP 库.用 Python 编写,真正的为人类着想. Python 标准库中的 urllib2 模块提供了你所需要的大多数 H ...

  9. 批量下载小说网站上的小说(python爬虫)

    随便说点什么 因为在学python,所有自然而然的就掉进了爬虫这个坑里,好吧,主要是因为我觉得爬虫比较酷,才入坑的. 想想看,你可以批量自动的采集互联网上海量的资料数据,是多么令人激动啊! 所以我就被 ...

  10. python 爬虫(二)

    python 爬虫 Advanced HTML Parsing 1. 通过属性查找标签:基本上在每一个网站上都有stylesheets,针对于不同的标签会有不同的css类于之向对应在我们看到的标签可能 ...

随机推荐

  1. stm32OLED多级菜单

    今天实现了OLED多级菜单的显示.我用的是stm32f103ve,和四脚的OLED屏幕,用了三个按键. 话不多说,直接上代码. 点击查看代码 //先定义按键功能结构体 typedef struct { ...

  2. RocketMQ(7) 消费幂等

    1 什么是消费幂等 当出现消费者对某条消息重复消费的情况时,重复消费的结果与消费一次的结果是相同的,并且多次消 费并未对业务系统产生任何负面影响,那么这个消费过程就是消费幂等的. 幂等:若某操作执行多 ...

  3. C++ //类模板与继承 //类模板与继承 //注意: //1.当子类继承父类是一个类模板时,子类在声名的时候,要指定出父类中T的类型 //2.如果不指定,编译器无法给子类分配内存 //3.如果想灵活指定出父类中的T的类型,子类也需要变为类模板

    1 #include <iostream> 2 #include <string> 3 #include<fstream> 4 using namespace st ...

  4. 各种O总结及阿里代码规范总结

    首先梳理下POJO POJO包括 DO/DTO/BO/VO(所有的POJO类属性必须使用包装数据类型.) 定义 DO/DTO/VO 等 POJO 类时,不要设定任何属性默认值. controller使 ...

  5. Linux Socket 摘要(二)(基于TCP的C/S基本实现,相关基础知识,非阻塞select)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  6. Android 开发Day4

    我们双击进入activity_main.xml 先将android.support.constraint.ConstraintLayout改为LinerLayout线性的,意思就是水平的的结构 并加入 ...

  7. UE干货| UE虚幻引擎调试神器—控件反射器

    一.打开控件反射器 可以通过窗口→开发者工具→控件反射器 打开: 也可以在umg编辑器上方控件反射器打开. 二.UE控件反射器使用方法 运行项目后,点击控件反射器的"选择可测试命中控件&qu ...

  8. TagProvider 与 Enricher 丰富日志

    TagProvider  [LogProperties] 与 [LogPropertyIgnore] 如果用在DTO不存在任何问题,如果用在Domain实体上,可能有点混乱. 您可能不希望因日志记录问 ...

  9. 深度解读UUID:结构、原理以及生成机制

    What 是 UUID UUID (Universally Unique IDentifier) 通用唯一识别码 ,也称为 GUID (Globally Unique IDentifier) 全球唯一 ...

  10. 使用元类实现Django的ORM

    一.ORM基本介绍 ORM 是 python编程语言后端web框架 Django的核心思想,"Object Relational Mapping",即对象-关系映射,简称ORM. ...