技术标签: 爬虫
这里的Lofter的工作是公司要的。主要目的是爬取大量用户的相册,之后做计算机视觉的训练集来用的。个人感觉这个是爬虫很常见的一个作用领域。(不过说实话,还是感觉有点low,觉得爬虫还是比较底层的工作。)
说回lofter。像这种爬取图片的一般都不难。但是Lofter这个网站,难就难在了其网页中用时间戳来做一系列的包参数,如果没有仔细研究的话,还是不好请求到包的。
下面看一下我是怎么完成整个工作的。
这里我借鉴了别人的工作基础。原帖见https://www.imooc.com/article/36533。
如果你认真研究完这个帖子,并且写一点代码来试一下里面关键的几步。就会明白里面包请求的规律。具体规律不赘述。
这里再根据我自己需求对代码做一些改变。并且加入协程来加快图片的下载速度。
这个部分对应的脚本是 lofter_spider_NameList_Concurrency.py
在上一步工作的基础之上,我们已经可以爬取某个用户主页里面的照片。要想获取大量的数据,只需要获取大量的用户ID即可。
这里我们从lofter的精选页http://loftermrjx.lofter.com/出发。可以看到这里面有推荐的照片。
点击进入第一个推荐照片,可以看到,下面有很多喜欢或者点赞的人。打开浏览器的调试工具(Chrome是F12),向下滑到最底部,点击底部的“查看更多”按钮,
这个时候可以看到弹出来的包里有一个XHR触发的包。
点进去这个包看一下响应(Response),你就可以看到这些点赞的人的信息。
关键怎么获得这个包的数据,一般来说是需要get请求加上headers的。不过先看一下这个包的请求地址
可以看到这个url= http://loftermrjx.lofter.com/morenotes?postid=280691700&offset=50,试着直接从浏览器访问一下,你会发现可以直接访问到这个页面,然后源码里可以看到详细信息。
红色方框里的就是我们想要的ID,就是那个" loup6 "。
到这里,我们再观察一下上面的点赞人对应的url,发现只有一个参数是未知的----postid。下面就要考虑怎么获得这个postid。其实很好理解:postid是针对每一篇发布的博客来说的,所以进入某个用户的归档页面(如果你认真研究了第一个部分中的内容就知道我在说什么),随便点击一篇博客,然后查看网页源码,搜索一下postid关键字,你就会看到其实postid就包含在源码内。
所以就很简单了,在用户的主页内遍历其所有的博文的同时,就可以获得postid,也就可以获得给这篇博文点赞的用户的ID。由此辐射,这个速度是非常快的,而且基本是停不下来的。
这里有一个问题就是说用户ID去重的问题。这里我用了Redis数据库中的Set,把爬来的用户ID写入对应数据库的set,在写入的时候由于set不含重复元素的特性,数据库会自动帮你去重,所以不用考虑爬取到重复的用户Id的问题了。
理论上来说,有了上面两个部分的工作,你已经可以爬取lofter全站所有用户的相册了。听上去是不是很酷。不过这需要很多时间。而且也没有人用自己的电脑这么做(太弱智了),一般都是放在线上的服务器做这个工作。同时你也需要很大的存储来存拿到的数据。
在我的工作中,我在自己的电脑上用一个周末爬到了268w用户ID,然后写了脚本把数据库导出成为json数据,然后在服务器中又重新读json数据到线上服务器的数据库中。
之后在线上服务器中,用Redis的List作为任务队列,通过Lpop()命令读取数据库中的用户ID。
把lofter_spider_NameList_Concurrency.py脚本通过pm2做进程守护(具体操作可以见我的其他博文)。之后就是时间和存储的问题了。
所有脚本和源码见以下
PCB画完进行规则检查时,总会出现各种各样的问题,有些问题莫名其妙不知其然。下面就我遇到的几个,记录下。1.Silk primitive without silk layer,意思就是有些丝印超出了丝印该在的区域。但是一般到规则检查时,丝印都摆放整齐了,不应该出现丝印在外面的情况啊,这是为何呢?一个元器件有好多个属性,一般我们把元器件的标号作为显示的丝印,而元器件的值却隐层起来,这导致隐层的丝印有可能跑到外面去,所以就报错了。方法呢,我们可以忽略该问题,要不就把隐藏的丝印摆放好就ok了。或者把上
本篇概要URL的结构HTTP头域HTTP状态码一个完整的HTTPget请求在上一篇我们简单介绍了HTTP协议的概念和知识,本篇我们来详细剖析一下HTTP的请求,将这两篇综合起来,我们就对HTTP有了基本的认识和了解了。URL结构解析通常情况下,我们发起一个HTTP请求都是通过访问一个URL网址来实现。比如我们打开百度的首页(http://www.baidu.com),就是对百度的服务器发起了一个H...
此脚本的主要目的:让浏览器客户端首先通过此代理,然后再访问目标网站。可基于特定的url做正则表达式匹配,然后替换为本地修改的版本。 主要用于浏览器内核研发过程中某些怀疑是特定网站JS脚本执行出错导致的渲染异常bug。可在JS脚本中插入console.log以定位出错点。var ProxyPort = 8888;var http = require('http'), net
MT6732Platform‐ 基础介绍LTE4G(64bit)4核芯片- 8926 与高通 芯片性能相当, BOMcost贴近目前6582主流价格,1.5GHz主频,HD分辨率屏,13MP摄像头;与MT67...
本文是对MongoDB副本集常用操作的一个汇总,同时也穿插着介绍了操作背后的原理及注意点。结合之前的文章:MongoDB副本集的搭建,大家可以在较短的时间内熟悉MongoDB的搭建和管理。下面的操作主要分为两个部分:1. 修改节点状态 主要包括: 1>将Primary节点降级为Secondary节点 2>冻结Secondary节点...
1.什么是决策树?决策树是一种常见的分类模型,基于树结构对数据进行划分。广泛应用于金融分控、医疗辅助诊断等诸多行业。决策树的步骤:2.决策树的构建决策树的构建过程是一个递归过程。伪代码如下:2.1信息增益...
环境:已经安装了git和maven,系统centos1.打包dubbo-admingit clone -b masterhttps://github.com/apache/incubator-dubbo-ops.gitmvn clean package -Dmaven.test.skip=true2.制作dubbo-admin镜像dubbo-admin下增加D...
一切都在代码里ps:说明一下,因为我这里没有使用 v-for 标签 ,循环,所以没有index 值,这里使用标签的id 值,代替 index准备工作html<div class="up1"> <p id="dxal" v-on:click="addStyleOrGetDate($event)" :class="activeClass =='dxal' ? 'active':'' " > 典型案例 </p>&
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.URL;import java.net.URLConnection;import com.eos.runtime.core.Trace...
1.dl:definition lists,自定义列表 列表中每个元素的标题使用(definition term)定义,后面跟随(definition description)用于描述列表中元素的内容.2.ul:unordered lists,无序列表 每一列使用(list item)标签定义,"列表项"的意思3.ol:ordered lists,有序列表 每一列使
概念理解: 基于经验和直觉推测程序中所有可能存在的各种错误,从而有针对性的设计测试用例的方法。 实践方法: Step1:列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据这些情况选择测试用例 Step2:注意积累与分享 实践心得: 1、有针对性的设计测试用例; 2、注意积累与分享 示例: 空格、不符合业务的负值或空值、同名等 常用...
前言简单用vscode配置 remote ssh可以实现,通过ssh 在线使用vscode编辑文件,很方便,也遇到一些坑。安装插件设置界面右键最左边tab栏:勾选 远程资源管理器 添加远程服务器点击 + 号,输入ssh指令连接:选择一个文件作为存储:注意:这里有个坑,如果你选择的文件没有访问权限,是无法显示出连接的,这里可能需要修改一下文件夹或文件的权限:点击编辑,设置完全控制权限:建立成功后:右键连接,选择平台,linux输入密码,连接成功:点击打开文件夹,