用go语言爬取珍爱网 | 第二回
昨天我们一起爬取珍爱网首页,拿到了城市列表页面,接下来在返回体城市列表中提取城市和url,即下图中的a标签里的href的值和innerText值。
提取a标签,可以通过CSS选择器来选择,如下:
$('#cityList>dd>a');就可以获取到470个a标签:
这里只提供一个思路,go语言标准库里没有CSS解析库,通过第三方库可以实现。具体可以参考文章:
https://my.oschina.net/2xixi/blog/488811
http://liyangliang.me/posts/2016/03/zhihu-go-insight-parsing-html-with-goquery/
这两篇文章都是用goquery解析 HTML,用到了库:
https://github.com/PuerkitoBio/goquery
也可以用xpath去解析html,可以参考:
https://github.com/antchfx/xquery
xpath和goquery相比还是比较麻烦的,通过以下这张图可以看出来goquery要活跃的多:
我们这里不用xpath,也不用goquery提取,用更加通用的正则表达式来提取。
从上图可以看出,返回体中的a标签里都是这种形式,XXX表示城市拼音,XX表示城市中文,其他的都一样。
<a href="http://www.zhenai.com/zhenghun/XXX"
class="">XX</a>
所以可以写出以下的正则表达式来匹配:
compile := regexp.MustCompile(`<a href="http://www.zhenai.com/zhenghun/[0-9a-z]+"[^>]*>[^<]+</a>`)
正则表达式说明:
1、href的值都类似http://www.zhenai.com/zhenghun/XX
2、XX可以是数字和小写字母,所以[0-9a-z],+表示至少有一个
3、[^>]*表示匹配不是>的其他字符任意次
4、[^<]+表示匹配不是<的其他字符至少一次
然后利用分组获取url和城市,代码如下:
func printAllCityInfo(body []byte){
//href的值都类似http://www.zhenai.com/zhenghun/XX
//XX可以是数字和小写字母,所以[0-9a-z],+表示至少有一个
//[^>]*表示匹配不是>的其他字符任意次
//[^<]+表示匹配不是<的其他字符至少一次
compile := regexp.MustCompile(`<a href="(http://www.zhenai.com/zhenghun/[0-9a-z]+)"[^>]*>([^<]+)</a>`)
submatch := compile.FindAllSubmatch(body, -1)
for _, matches := range submatch {
//打印
fmt.Printf("City:%s URL:%s\n", matches[2], matches[1])
}
//可以看到匹配个数为470个
fmt.Printf("Matches count: %d\n", len(submatch))
}
那么提取URL和City的完整代码如下:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"golang.org/x/text/transform"
//"golang.org/x/text/encoding/simplifiedchinese"
"io"
"golang.org/x/text/encoding"
"bufio"
"golang.org/x/net/html/charset"
"regexp"
)
func main() {
//返送请求获取返回结果
resp, err := http.Get("http://www.zhenai.com/zhenghun")
if err != nil {
panic(fmt.Errorf("Error: http Get, err is %v\n", err))
}
//关闭response body
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Println("Error: statuscode is ", resp.StatusCode)
return
}
//utf8Reader := transform.NewReader(resp.Body, simplifiedchinese.GBK.NewDecoder())
utf8Reader := transform.NewReader(resp.Body, determinEncoding(resp.Body).NewDecoder())
body, err := ioutil.ReadAll(utf8Reader)
if err != nil {
fmt.Println("Error read body, error is ", err)
}
printAllCityInfo(body)
//打印返回值
//fmt.Println("body is ", string(body))
}
func determinEncoding(r io.Reader) encoding.Encoding {
//这里的r读取完得保证resp.Body还可读
body, err := bufio.NewReader(r).Peek(1024)
if err != nil {
fmt.Println("Error: peek 1024 byte of body err is ", err)
}
//这里简化,不取是否确认
e, _, _ := charset.DetermineEncoding(body, "")
return e
}
func printAllCityInfo(body []byte){
//href的值都类似http://www.zhenai.com/zhenghun/XX
//XX可以是数字和小写字母,所以[0-9a-z],+表示至少有一个
//[^>]*表示匹配不是>的其他字符任意次
//[^<]+表示匹配不是<的其他字符至少一次
compile := regexp.MustCompile(`<a href="(http://www.zhenai.com/zhenghun/[0-9a-z]+)"[^>]*>([^<]+)</a>`)
/*matches := compile.FindAll(body, -1)
//matches是二维数组[][]byte
for _, m := range matches {
fmt.Printf("%s\n", m)
}
*/
submatch := compile.FindAllSubmatch(body, -1)
//submatch是三维数组[][][]byte
/* for _, matches := range submatch {
//[][]byte
for _, m := range matches {
fmt.Printf("%s ", m)
}
fmt.Println()
}*/
for _, matches := range submatch {
//打印
fmt.Printf("City:%s URL:%s\n", matches[2], matches[1])
}
//可以看到匹配个数为470个
fmt.Printf("Matches count: %d\n", len(submatch))
//打印abc
//fmt.Printf("%s\n", []byte{97,98,99})
}
运行后,可以看到输出了URL和City:
今天我们完成了URL和城市的提取,明天我们将利用URL,来进一步分析城市的男女性个人信息。
本公众号免费提供csdn下载服务,海量IT学习资源,如果你准备入IT坑,励志成为优秀的程序猿,那么这些资源很适合你,包括但不限于java、go、python、springcloud、elk、嵌入式 、大数据、面试资料、前端 等资源。同时我们组建了一个技术交流群,里面有很多大佬,会不定时分享技术文章,如果你想来一起学习提高,可以公众号后台回复【2】,免费邀请加技术交流群互相学习提高,会不定期分享编程IT相关资源。
扫码关注,精彩内容第一时间推给你
用go语言爬取珍爱网 | 第二回的更多相关文章
- 用go语言爬取珍爱网 | 第一回
我们来用go语言爬取"珍爱网"用户信息. 首先分析到请求url为: http://www.zhenai.com/zhenghun 接下来用go请求该url,代码如下: packag ...
- 用go语言爬取珍爱网 | 第三回
前两节我们获取到了城市的URL和城市名,今天我们来解析用户信息. 用go语言爬取珍爱网 | 第一回 用go语言爬取珍爱网 | 第二回 爬虫的算法: 我们要提取返回体中的城市列表,需要用到城市列表解析器 ...
- Python爬虫之爬取慕课网课程评分
BS是什么? BeautifulSoup是一个基于标签的文本解析工具.可以根据标签提取想要的内容,很适合处理html和xml这类语言文本.如果你希望了解更多关于BS的介绍和用法,请看Beautiful ...
- GoLang爬取花瓣网美女图片
由于之前一直想爬取花瓣网(http://huaban.com/partner/uc/aimeinv/pins/) 的图片,又迫于没时间,所以拖了很久. 鉴于最近在学go语言,就刚好用这个练手了. 预览 ...
- 网络爬虫之定向爬虫:爬取当当网2015年图书销售排行榜信息(Crawler)
做了个爬虫,爬取当当网--2015年图书销售排行榜 TOP500 爬取的基本思想是:通过浏览网页,列出你所想要获取的信息,然后通过浏览网页的源码和检查(这里用的是chrome)来获相关信息的节点,最后 ...
- 使用python爬取东方财富网机构调研数据
最近有一个需求,需要爬取东方财富网的机构调研数据.数据所在的网页地址为: 机构调研 网页如下所示: 可见数据共有8464页,此处不能直接使用scrapy爬虫进行爬取,因为点击下一页时,浏览器只是发起了 ...
- Node.js爬虫-爬取慕课网课程信息
第一次学习Node.js爬虫,所以这时一个简单的爬虫,Node.js的好处就是可以并发的执行 这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让 ...
- python 爬虫之爬取大街网(思路)
由于需要,本人需要对大街网招聘信息进行分析,故写了个爬虫进行爬取.这里我将记录一下,本人爬取大街网的思路. 附:爬取得数据仅供自己分析所用,并未用作其它用途. 附:本篇适合有一定 爬虫基础 crawl ...
- 基于爬取百合网的数据,用matplotlib生成图表
爬取百合网的数据链接:http://www.cnblogs.com/YuWeiXiF/p/8439552.html 总共爬了22779条数据.第一次接触matplotlib库,以下代码参考了matpl ...
随机推荐
- C#基础——事件初步
事件是C#语言的重要成员之一,初学者往往不能很好的去理解和运用事件,特别是自定义事件.在这里将以较简单的方式呈现事件最基本的用法. 1.事件的定义 给事件下定义是一个较困难的事,因为它体现的是对象与对 ...
- 史无前例的RNN讲解
这篇博客不是一篇讲解原理的博客,这篇博客主要讲解time_steps,如果这篇博客没有让你明白time_steps,那么算我无能. 我曾翻阅各大网站,各大博客,他们的对RNN中time_steps的讲 ...
- 拆解大数据总线平台DBus的系统架构
Dbus所支持两类数据源的实现原理与架构拆解. 大体来说,Dbus支持两类数据源: RDBMS数据源 日志类数据源 一.RMDBMS类数据源的实现 以mysql为例子. 分为三个部分: 日志抽取模块 ...
- Spring Security Oauth2 自定义 OAuth2 Exception
付出就要得到回报,这种想法是错的. 前言 在使用Spring Security Oauth2登录和鉴权失败时,默认返回的异常信息如下 { "error": "unauth ...
- Net基础篇_学习笔记_第十二天_面向对象继承(父类和子类)
继承 我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,单独的封装到一个类中,作为这些类的父类.Student.Teacher.Driver 子类 派生类Person ...
- (六十八)c#Winform自定义控件-DEMO整理
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- 解决python -m pip install --upgrade pip 升级不成功问题
1.使用命令出现. You are , however version is available. You should consider upgrading via the 'python -m p ...
- mybatis #号与$号的区别
区别: 在sql中当传入的参数是字符型,则用#号会带上单引号,不会引起sql注入: 在sql中当传入的参数是字符型,则用$号不会带上单引号,会引起sql注入: 使用范围: 当传入的参数用于查询条件,尽 ...
- TLC5615
#include <reg51.h> #include "TLC5615.c" code uchar seven_seg[] = {0xc0, 0xf9, 0xa4, ...
- 获取contenteditable区域光标所在位置信息
在我们使用contenteditable编辑时,有时需要光标位置的信息. <div contenteditable="true" style="min-height ...