广告
返回顶部
首页 > 资讯 > 数据库 >数据采集实战(一)-
  • 712
分享到

数据采集实战(一)-

数据采集实战(一)- 2017-02-11 10:02:04 712人浏览 无得
摘要

概述 最近在学习python的各种数据分析库,为了尝试各种库中各种分析算法的效果,陆陆续续爬取了一些真实的数据来。 顺便也练习练习爬虫,踩了不少坑,后续将采集的经验逐步分享出来,希望能给后来者一些参考,也希望能够得到先驱者的指点! 采集工

数据采集实战(一)-

概述

最近在学习python的各种数据分析库,为了尝试各种库中各种分析算法的效果,陆陆续续爬取了一些真实的数据来。

顺便也练习练习爬虫,踩了不少坑,后续将采集的经验逐步分享出来,希望能给后来者一些参考,也希望能够得到先驱者的指点!

采集工具

其实基本没用过什么现成的采集工具,都是自己通过编写代码来采集,虽然耗费一些时间,但是感觉灵活度高,可控性强,遇到问题时解决的方法也多。

一般根据网站的情况,如果提供api最好,直接写代码通过访问API来采集数据。
如果没有API,就通过解析页面(html)来获取数据。

本次采集的数据是链家网上的成交数据,因为是学习用,所以不会去大规模的采集,只采集了南京各个区的成交数据。

采集使用puppeteer库,Puppeteer 是一个 node 库,它提供了高级的 API 并通过 DevTools 协议来控制 Chrome(或Chromium)。
通俗来说就是一个 headless chrome 浏览器: https://GitHub.com/puppeteer/puppeteer

通过 puppeteer,可以模拟网页的手工操作方式,也就是说,理论上,能通过浏览器正常访问看到的内容就能采集到。

采集过程

其实数据采集的代码并不复杂,时间主要花在页面的分析上了。

链家网的成交数据不用登录也可以访问,这样就省了很多的事情。
只要找出南京市各个区的成交数据页面的URL,然后访问就行。

页面分析

下面以栖霞区的成交页面为例,分析我们可能需要的数据。

页面URL: Https://nj.lianjia.com/chengjiao/qixia/
image.png
根据页面,可以看出重复的主要是红框内的数据,其中销售人员的姓名涉及隐私,我们不去采集。
采集的数据分类为:(有的户型可能没有下面列的那么全,缺少房屋优势字段,甚至成交价格字段等等)

  1. name: 小区名称和房屋概要,比如:新城香悦澜山 3室2厅 87.56平米
  2. houseInfo: 房屋朝向和装修情况,比如:南 北 | 精装
  3. dealDate: 成交日期,比如:2021.06.14
  4. totalPrice: 成交价格(单位: 万元),比如:338万
  5. positionInfo: 楼层等信息,比如:中楼层(共5层) 2002年建塔楼
  6. unitPrice: 成交单价,比如:38603元/平
  7. advantage: 房屋优势,比如:房屋满五年
  8. listPrice: 挂牌价格,比如:挂牌341万
  9. dealCycleDays: 成交周期,比如:成交周期44天

核心代码

链家网上采集房产成交数据很简单,我在采集过程中遇到的唯一的限制就是根据检索条件,只返回100页的数据,每页30条。
也就是说,不管什么检索条件,链家网只返回前3000条数据。
可能这也是链家网控制服务器访问压力的一个方式,毕竟如果是正常用户访问的话,一般也不会看3000条那么多,返回100页数据绰绰有余。

为了获取想要的数据,只能自己设计下检索条件,保证每个检索条件下的数据不超过3000条,最后自己合并左右的采集结果,去除重复数据。

这里,只演示如何采集数据,具体检索条件的设计,有兴趣根据自己需要的数据尝试下即可,没有统一的方法。

通过puppeteer采集数据,主要步骤很简单:

  1. 启动浏览器,打开页面
  2. 解析当前页面,获取需要的数据(也就是上面列出的9个字段的数据)
  3. 进入下一页
  4. 如果是最后一页,则退出程序
  5. 如果不是最后一页,进入步骤2

初始化并启动页面

import puppeteer from "puppeteer";

(async () => {
  // 启动页面,得到页面对象
  const page = await startPage();
})();

// 初始化浏览器
const initBrowser = async () => {
  const browser = await puppeteer.launch({
    args: ["--no-sandbox", "--start-maximized"],
    headless: false,
    userDataDir: "./user_data",
    ignoreDefaultArgs: ["--enable-automation"],
    executablePath:
      "C:\Program Files\Google\Chrome\Application\chrome.exe",
  });

  return browser;
};

// 启动页面
const startPage = async (browser) => {
  const page = await browser.newPage();
  await page.setViewport({ width: 1920, height: 1080 });

  return page;
};

采集数据

import puppeteer from "puppeteer";

(async () => {
  // 启动页面,得到页面对象
  const page = await startPage();
  
  // 采集数据
  await nanJin(page);
})();

const mapAreaPageSize = [
  // { url: "https://nj.lianjia.com/chengjiao/gulou", name: "gulou", size: 2 }, // 测试用
  { url: "https://nj.lianjia.com/chengjiao/gulou", name: "gulou", size: 30 },
  { url: "https://nj.lianjia.com/chengjiao/jianye", name: "jianye", size: 20 },
  {
    url: "https://nj.lianjia.com/chengjiao/qinhuai",
    name: "qinhuai",
    size: 29,
  },
  { url: "https://nj.lianjia.com/chengjiao/xuanwu", name: "xuanwu", size: 14 },
  {
    url: "https://nj.lianjia.com/chengjiao/yuhuatai",
    name: "yuhuatai",
    size: 14,
  },
  { url: "https://nj.lianjia.com/chengjiao/qixia", name: "qixia", size: 14 },
  {
    url: "https://nj.lianjia.com/chengjiao/jiangning",
    name: "jiangning",
    size: 40,
  },
  { url: "https://nj.lianjia.com/chengjiao/pukou", name: "pukou", size: 25 },
  { url: "https://nj.lianjia.com/chengjiao/liuhe", name: "liuhe", size: 4 },
  { url: "https://nj.lianjia.com/chengjiao/lishui", name: "lishui", size: 4 },
];

// 南京各区成交数据
const nanJin = async (page) => {
  for (let i = 0; i < mapAreaPageSize.length; i++) {
    const areaLines = await nanJinArea(page, mapAreaPageSize[i]);

    // 分区写入csv
    await saveContent(
      `./output/lianjia`,
      `${mapAreaPageSize[i].name}.csv`,
      areaLines.join("
")
    );
  }
};

const nanJinArea = async (page, m) => {
  let areaLines = [];
  for (let i = 1; i <= m.size; i++) {
    await page.goto(`${m.url}/pg${i}`);
    // 等待页面加载完成,这是显示总套数的div
    await page.$$("div>.total.fs");
    await mouseDown(page, 800, 10);

    // 解析页面内容
    const lines = await parseLianjiaData(page);
    areaLines = areaLines.concat(lines);

    // 保存页面内容
    await savePage(page, `./output/lianjia/${m.name}`, `page-${i}.html`);
  }

  return areaLines;
};

// 解析页面内容
// 1. name: 小区名称和房屋概要
// 2. houseInfo: 房屋朝向和装修情况
// 3. dealDate: 成交日期
// 4. totalPrice: 成交价格(单位: 万元)
// 5. positionInfo: 楼层等信息
// 6. unitPrice: 成交单价
// 7. advantage: 房屋优势
// 8. listPrice: 挂牌价格
// 9. dealCycleDays: 成交周期
const parseLianjiaData = async (page) => {
  const listContent = await page.$$(".listContent>li");

  let lines = [];
  for (let i = 0; i < listContent.length; i++) {
    try {
      const name = await listContent[i].$eval(
        ".info>.title>a",
        (node) => node.innerText
      );
      const houseInfo = await listContent[i].$eval(
        ".info>.address>.houseInfo",
        (node) => node.innerText
      );
      const dealDate = await listContent[i].$eval(
        ".info>.address>.dealDate",
        (node) => node.innerText
      );
      const totalPrice = await listContent[i].$eval(
        ".info>.address>.totalPrice>.number",
        (node) => node.innerText
      );
      const positionInfo = await listContent[i].$eval(
        ".info>.flood>.positionInfo",
        (node) => node.innerText
      );
      const unitPrice = await listContent[i].$eval(
        ".info>.flood>.unitPrice>.number",
        (node) => node.innerText + "元/平"
      );
      let advantage = "";
      try {
        advantage = await listContent[i].$eval(
          ".info>.dealHouseInfo>.dealHouseTxt>span",
          (node) => node.innerText
        );
      } catch (err) {
        console.log("err is ->", err);
        advantage = "";
      }

      const [listPrice, dealCycleDays] = await listContent[i].$$eval(
        ".info>.dealCycleeInfo>.dealCycleTxt>span",
        (nodes) => nodes.map((n) => n.innerText)
      );

      console.log("name: ", name);
      console.log("houseInfo: ", houseInfo);
      console.log("dealDate: ", dealDate);
      console.log("totalPrice: ", totalPrice);
      console.log("positionInfo: ", positionInfo);
      console.log("unitPrice: ", unitPrice);
      console.log("advantage: ", advantage);
      console.log("listPrice: ", listPrice);
      console.log("dealCycleDays: ", dealCycleDays);
      lines.push(
        `${name},${houseInfo},${dealDate},${totalPrice},${positionInfo},${unitPrice},${advantage},${listPrice},${dealCycleDays}`
      );
    } catch (err) {
      console.log("数据解析失败:", err);
    }
  }

  return lines;
};

我是把要采集的页面列在 const mapAreaPageSize 这个变量中,其中 url 是页面地址,size 是访问多少页(根据需要,并不是每个检索条件都要访问100页)。

采集数据的核心在 parseLianjiaData 函数中,通过 chrome 浏览器的debug模式,找到每个数据所在的页面位置。
puppeteer提供强大的html 选择器功能,通过html元素的 idclass 可以很快定位数据的位置(如果用过Jquery,很容易就能上手)。
这样,可以避免写复杂的正则表达式,提取数据更方便。

采集之后,我最后将数据输出成 csv 格式。

注意事项

爬取数据只是为了研究学习使用,本文中的代码遵守:

  1. 如果网站有 robots.txt,遵循其中的约定
  2. 爬取速度模拟正常访问的速率,不增加服务器的负担
  3. 只获取完全公开的数据,有可能涉及隐私的数据绝对不碰
您可能感兴趣的文档:

--结束END--

本文标题: 数据采集实战(一)-

本文链接: https://www.lsjlt.com/news/8554.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 数据采集实战(一)-
    概述 最近在学习python的各种数据分析库,为了尝试各种库中各种分析算法的效果,陆陆续续爬取了一些真实的数据来。 顺便也练习练习爬虫,踩了不少坑,后续将采集的经验逐步分享出来,希望能给后来者一些参考,也希望能够得到先驱者的指点! 采集工...
    99+
    2017-02-11
    数据采集实战(一)-
  • 数据采集实战(三)-
    1. 概述 王者荣耀是一直都挺喜欢的一个手游,玩了好几年,最近一段开始喜欢看比赛,所以想着采集点数据看看各个战队或者选手的情况。 顺便也练习练习 puppeteer 的使用。 数据来源于:尚牛电竞 。 2. 采集流程 王者荣耀最近正在进行...
    99+
    2020-07-29
    数据采集实战(三)-
  • 数据采集实战(四)-
    1. 概述 前段时间在看一本很多人推荐的线性代数教材《线性代数应该这样学》第三版,这一版每个章节都有大量的习题。 官方网站上虽然按照章节提供了习题的答案,一来因为网站是国外的,访问不流畅,二来答案中还夹杂着广告,影响查看。 所以,想试着将...
    99+
    2019-04-29
    数据采集实战(四)-
  • 数据采集实战(五)-
    1. 概述 现在学校越来越重视孩子课外知识的掌握,给孩子挑选课外书一般都是参考学校或者家长之间的推荐。 有时,也会想看看在儿童阶段,目前到底流行的是些什么样的书。 ​ 于是,就简单写了这个小爬虫,采集了畅销童书的前20名。 要想采集更多的...
    99+
    2015-05-29
    数据采集实战(五)-
  • 数据采集实战(二)-
    1. 概述 京粉(https://union.jd.com/)是京东联盟下的网站,通过分享其中的商品链接可以赚取佣金,类似淘客联盟。 采集京粉的商品,既可以练习 puppeteer的使用,平时想在京东购物时,也能用得上(采集看看...
    99+
    2015-01-09
    数据采集实战(二)-
  • Python采集C站热榜数据实战示例
    目录前言功能实现解析数据保存数据总结前言 大家好,我们今天来爬取c站的热搜榜,把其文章名称,链接和作者获取下来,我们保存到本地,我们通过测试,发现其实很简单,我们只要简单获取数据就可...
    99+
    2023-05-19
    Python采集C站热榜数据 Python 数据采集
  • Python实战使用XPath采集数据示例解析
    目录lxml发送请求明确需求:解析数据保存数据lxml lxml 是 Python 的一个库,用于解析和呈现 XML 和 HTML。它支持多种内置和第三方 XML 和 HTML 标记...
    99+
    2023-05-16
    Python XPath采集数据 Python XPath
  • 第02期:Prometheus 数据采集(一)
    上篇文章(第01期:详解 Prometheus 专栏开篇)介绍了 Prometheus 的架构,本文开始将介绍 Prometheus 数据采集。本文首先会介绍采集数据的格式和分类,然后会给出一些使用上的建议。 一、采集数据格式及分类 1....
    99+
    2022-04-30
    第02期:Prometheus 数据采集(一)
  • Python+Selenium实现一键摸鱼&采集数据
    目录前言应用场景代码一键摸鱼(打开多个网页编写bat一键数据采集前言 将Selenium程序编写为 .bat 可执行文件,从此一键启动封装好的Selenium程序,省时省力还可以复用...
    99+
    2022-11-11
  • 数据采集 - Marvin
                     链接:https://bdcc.bigdataedu.org/block/48(需账号登录)...
    99+
    2016-08-03
    数据采集 - Marvin
  • php实现大数据采集
    随着互联网的不断发展,数据采集成为了人们获取信息的重要手段。然而,随着数据量的不断增加,传统的手动采集方法已经无法满足需求,因此,大数据采集技术成为了关键。在这里,我们来介绍一下php实现大数据采集的方法。一、 数据采集流程数据采集流程通常...
    99+
    2023-05-24
  • 【Python实战】Python采集情感音频
    成年人的世界真不容易啊 总是悲伤大于欢喜 爱情因为懵懂而快乐 却走进了复杂和困惑的婚姻 前言 我最近喜欢去听情感类的节目,比如说,婚姻类,我可能老了吧。我就想着怎么把音乐下载下来了,保存到手机上,方便我们业余时间去听。 环境使用 ...
    99+
    2023-09-05
    python 爬虫 音视频
  • 用vue设计一个数据采集器
    目录场景核心问题状态监听状态监听优势状态监听劣势重构实现思路依赖收集总结场景 在业务上现在有一个场景,当发生业务行为变化时,需要对各个模块的行为进行数据收集,数据用途可以用作回顾,...
    99+
    2022-11-12
  • Python爬虫实战演练之采集糗事百科段子数据
    目录知识点爬虫基本步骤:爬虫代码导入所需模块获取网页地址发送请求数据解析保存数据运行代码,得到数据知识点 1.爬虫基本步骤 2.requests模块 3.parsel模块 4.xpa...
    99+
    2022-11-12
  • Python采集电影评论实战示例
    目录数据采集发送请求解析数据获取内容输出内容总结数据采集 我们上一篇介绍了,如何采集王者皮肤,买不起皮肤,当个桌面壁纸挺好的。我们今天来学习如何采集电影评论,看看这个电影好不好看。 ...
    99+
    2023-05-16
    Python采集电影评论 Python采集
  • Python采集王者最低战力信息实战示例
    目录🥩数据采集🍖确定网址请求URL:请求方式:参数:请求示例返回示例🍖获取数据🍖解析数据保存数据🥩数据采集 🍖确定网址 王者新赛季马上就要开始了,大家都开始冲榜了,准备拿一个小省标,...
    99+
    2023-05-16
    Python采集王者战力信息 Python 采集
  • Python爬虫实战演练之采集拉钩网招聘信息数据
    目录本文要点:环境介绍本次目标爬虫块使用内置模块:第三方模块:代码实现步骤: (爬虫代码基本步骤)开始代码导入模块发送请求解析数据加翻页保存数据运行代码,得到数据本文要点: ...
    99+
    2022-11-12
  • 亚马逊数据采集
    爬虫技术:通过网页抓取、HTTP请求、DNS解析等技术手段来获取网站数据。 用户行为数据:通过用户访问网站的行为记录来获取用户信息,包括访问时间、访问页面、跳出率、购买记录等。 第三方API接口:通过第三方API接口,可以获取网站的用户信...
    99+
    2023-10-27
    亚马逊 数据采集
  • 数据采集与存储
    1.2 数据采集技术的功能及特点 数据采集技术是指通过各种手段和工具,从各种数据源中采集、提取和处理数据的过程。数据采集技术的主要功能包括: 数据源的识别:通过各种手段找到需要采集数据的来源,包括网站...
    99+
    2023-09-15
    python mysql spark
  • Hive实战之Youtube数据集
    Hive是一个基于Hadoop的数据仓库基础设施,可以用于处理大规模的结构化数据。在Hive中,使用类似SQL的查询语言来处理数据,...
    99+
    2023-09-15
    Hive
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作