之前用php写过一个爬虫,同样是获取局域网的网站数据,这次我使用相同的网络环境,更低的电脑配置,使用ruby来再次爬虫,惊人的发现ruby使用自带的类库net/http爬取速度要远远超过php的curl_*函数。在循环爬取网页时,ruby的cpu占用率上达到了40-70%,而php仅仅使用了可怜的5-10%,目前还不知这其中的奥秘,理论上都是使用的单线程,差距这么大是解释器还是类库的差距呢?

不管了,以后再做性能测试,简单说一下过程。

安装两个包

gem install mysql2

gem install nokogiri

导入三个相当必要的包

require 'net/http'
require 'mysql2'
require 'nokogiri'
  1. net/http相当于php的curl函数,可以实现http请求,模拟浏览器一样的请求,发送给http服务器得到返回数据。
  2. mysql2,mysql连接,相当于java的jdbc,实现数据库读写
  3. nokogiri,这是一个html的dom解析类库,可以快速的解析html,获得节点下的属性,文本,子节点等

开始

完整代码

require 'net/http'
require 'mysql2'
require 'nokogiri' client = Mysql2::Client.new(:host => 'localhost',:username => 'root', :database => 'cslg', :encoding => 'utf8'); url = [] #示例网站罢了
url << "http://www.baidu.com"
sql = "" url.each do |u|
u = URI(u);
http = Net::HTTP.new(u.host,u.port);
headers = {
'Cookie'=>''#设置访问时的cookie,如果没有则不需要传入这个headers散列
} doc = http.get(u,headers) #发送请求 html = Nokogiri::HTML(doc.body) #html格式化 tds=html.xpath("//td") #找到所有的td标签 #过滤爬取得空或者废页面,根据实际返回页面的数据量,比如td标签过少的就是空的,不存在的
if tds.size < 79
next
end #数据库语句准备好
sql ="insert into teacher_base_info values(null"
tds.each_with_index do |td,i|
if i<74 && i>8
text = td.text.strip
if !(text.include?":")
sql+=",'#{text.to_s.addslashes}'"
elsif i==57 || i==66 || i==73
#拼接数据库语句
sql+=",'#{text.split(":")[1].to_s.addslashes}'"
end
end
end
sql+=")"
puts sql
client.query(sql) end

分析

首先连接到数据库:

client = Mysql2::Client.new(:host => 'localhost',:username => 'root', :password=>'' :database => 'xxx', :encoding => 'utf8');

主机,用户名,密码,数据库,编码等参数

需要的变量:

url = []
url << "http://www.baidu.com"
sql = ""

主要是地址,需要遍历的话则使用数组存储地址,然后是数据库语句存储字符串,后面用于拼接语句

对数组遍历,开始爬虫:

	u = URI(u);

    http = Net::HTTP.new(u.host,u.port);
headers = {
'Cookie'=>''#设置访问时的cookie,如果没有则不需要传入这个headers散列
} doc = http.get(u,headers)

对于网页的访问,需要提供的有:地址,端口,get参数(或者post参数),还有header中的信息

那么对于那些需要登录的网站,往往需要提供cookie来保持会话,那么headers变量可以存储散列,将键值对放入其中,就可以发送请求同时发送已经登录获得的cookie

cookie的值从开发者工具中获取,chrome F12

headers变量键值对遵循上面的规则,并且Ruby中使用“=>”定义散列中的元素

URI类,URI方法可以格式化字符串地址,成为uri对象

Net::HTTP.new()返回一个http对象,调用get方法可以访问地址,第一个是uri对象,第二个是header散列,提供header信息

如果我的地址中存在?x=xx&y=yy&z=zz这样的的get参数呢?

依然使用上述方法!将u=URI(地址包括get)取得的u传入http.get的第一个参数,get中的参数会被自动发送到http,并不会遗漏

解析html

爬下来之后,需要对html进行解析,ruby我采用了nokogiri,php可以使用“Simple HTML DOM”

使用nokogiri格式化取得的html文件:

html = Nokogiri::HTML(doc.body)   #html格式化

tds=html.xpath("//td")   #找到所有的td标签

xpath方法可以获得所有指定标签,前面要加“//”

tds将会是一个对象数组,可以用each或者each_with_index遍历

通过.text.to_s获取标签里的内容,就像js的innerText!

nokogiri使用说明

拼接sql语句

sql+=",'#{text.to_s.addslashes}'"
sql+=",'#{text.split(":")[1].to_s.addslashes}'"

将逗号放在前面会相对方便,不会有多余的“,”出现

addslashes是我自己写的方法,扩展了ruby的String类,主要是为了避免sql语句中出现单引号!这很重要,因为爬下来的数据经常会出现单引号,一般我转化为html的转义符,这是安全的

class String
def addslashes
self.gsub(/\'/,'&apos;')
end
end

最后:数据爬取简单,数据分析难!写入数据库要做很多的分析,如何解析html或者json,如何格式化字符串,得到想要的内容,如何建立合适的表,合适的字段,并且如何将数据一一对应的插入进去,这些比爬虫本身复杂多

Ruby爬虫header发送cookie,nokogiri解析html数据的更多相关文章

  1. header发送Cookie

    Cookie传达给客户端的原理 平时执行setcookie('key1', 'value1');这样的代码时,浏览器就会收到cookie并保存,但我们并不能从echo出去的内容中看到cookie内容 ...

  2. 爬虫header和cookie

    def on_start(self): self.crawl('http://bbs.byr.cn/board/Python', headers={'X-Requested-With': 'XMLHt ...

  3. postman5.0.2_0+postmanInterceptor0.2.22_0下载安装,可发送header头 cookie 参数

    Postman是chrome上一个非常好用的http客户端插件,可惜由于chrome安全的限制,发不出带cookie的请求.如果想要发送带cookie的请求,需要开启Interceptor 安装方法: ...

  4. ruby 爬虫爬取拉钩网职位信息,产生词云报告

    思路:1.获取拉勾网搜索到职位的页数 2.调用接口获取职位id 3.根据职位id访问页面,匹配出关键字 url访问采用unirest,由于拉钩反爬虫,短时间内频繁访问会被限制访问,所以没有采用多线程, ...

  5. 跨域问题,前端主动向后台发送cookie

    跨域是什么? 从一个域名的网页访问另一个域名的资源,就会出现跨域.只要协议.端口.域名有一个不同就会出现跨域 例如: 1.协议不同  http://www.baidu.com:80 和 https:/ ...

  6. Jmeter(一)http接口添加header和cookie --转载

    Jmeter(一)http接口添加header和cookie   HTTP信息头管理器在Jmeter的使用过程中起着很重要的作用,通常我们在通过Jmeter向服务器发送http请求(get或者post ...

  7. Header和Cookie相关内容

    相信很多同学都对HTTP的header和cookie,和session都有疑问,因为我们开发的时候一般都需要请求网络获取数据,有时候还需要带cookie或者带特殊的字段发起请求. 现在我们就来简单的了 ...

  8. 对EL自己以及对于param、header、cookie的相关应用的相关知识点的复习

    EL表达式语言是一种可以计算和输出的java对象的简单语言. 列入请求语句为下面的方式:request.setAttribute("username","zhangsan ...

  9. Android端接收和发送cookie

    流程: 首先android端使用HttpClient的方式发送HTTP请求,此时服务器创立cookie,并发送cookie给android端,android端再将cookie保存起来,在需要发送coo ...

随机推荐

  1. Vus the Cossack and Strings(Codeforces Round #571 (Div. 2))(大佬的位运算实在是太强了!)

    C. Vus the Cossack and Strings Vus the Cossack has two binary strings, that is, strings that consist ...

  2. 60年前美国军方的这个编程原则,造就了多少伟大的框架--KISS原则

    摘自:https://kb.cnblogs.com/page/654057/ 作者: 贺卓凡  来源: ImportSource  发布时间: 2020-01-23 19:52  阅读: 2324 次 ...

  3. 数据分析-Numpy-Pandas

    补充上一篇未完待续的Numpy知识点 索引和切片 数组和标量(数字)之间运算 li1 = [ [1,2,3], [4,5,6] ] a = np.array(li1) a * 2 运行结果: arra ...

  4. 常用的模型集成方法介绍:bagging、boosting 、stacking

    本文介绍了集成学习的各种概念,并给出了一些必要的关键信息,以便读者能很好地理解和使用相关方法,并且能够在有需要的时候设计出合适的解决方案. 本文将讨论一些众所周知的概念,如自助法.自助聚合(baggi ...

  5. idea快捷键(最常用)

    --跳到上一空白行 ctrl+alt+enter --跳到下一空白行 shift+enter --为代码生成包裹快(try catch等) ctrl+alt+t --跳到某行 ctrl+g --实现父 ...

  6. 第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第十天】(单点登录系统实现)

    https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...

  7. $n$阶常微分方程通解中常数独立的意义

    丁同仁,李承治编<常微分方程教程>第二版的定义1.3给出了 $ n$ 阶常微分方 程 $ {\displaystyle F(x,y,y',\cdots,y^{(n)})=0 \ \ \ \ ...

  8. Jupyter_Notebook

    TA-lib指标库地址 http://github.com/xingbuxing/TA-Lib-in-chinese 1.Jupter是基于网页端写代码,属于一种交互式的编程,除了在上面写代码之外还可 ...

  9. Scapy-ARPspoof学习

    layout title tag date post Scapy模块学习之ARP欺骗 Python 2018-05-08 from scapy.all import Ether,ARP,sendp,g ...

  10. 项目server中设置session timeout遇到的问题

    RT:在项目server中的web.xml设置session timeout=10,当10分钟后,继续右键执行jsp文件,运行失败,如下图所示: 但是单独启动tomcat server后,在浏览器中输 ...