爬虫功能介绍
此项目主要用于爬取BOSS直聘网的职位,薪资,学历,任职要求,爬取的内容用myql存储
可以输入爬取职位,爬取页数,爬取一页的时间大概需要2秒
利用了多个useraget和cookie做测试,测试反扒策略
1、分析页面url
https://www.zhipin.com/c100010000/?query=Java&page=2
请求的url= https://www.zhipin.com/c100010000/
请求的参数=query=Java&page=2
页面跳转为 page+1
单页最大page = 10 //未登录的情况下
2、根据你要获取的信息发送请求
package main
import (
"fmt"
"github.com/PuerkitoBio/goquery"
"github.com/garyburd/redigo/redis"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"io/ioutil"
"log"
"math/rand"
"net/http"
"os"
"strconv"
"time"
)
// 公司介绍
type CompanyStruct struct{
JobLind string `db:"招聘者"`
CompanyInfo string `db:"公司信息"`
JobType string `db:"工作类型"`
ForCompany string `db:"招聘公司"`
InLand string `db:"在何地招聘"`
Mania string `db:"薪资范畴"`
}
var (
//__zp_stoken__="9a3dBF3MCmyPZ4Zs9eRYGXGUR-Ugs3h8Pz03%2FrBtAtNgB67REb52tBBbLpjxcmw7ZppohumsjJF79M4BFI5NcaRf4uw%3D%3D";
//__zp_stoken__="9a3dBF3MCmyPZ4Zs9eRYGXGUR-Qbi93bx3nbc%2Beassyi2tITP4L7hUXliwMp6lk%2BvoQ%2FvUQqVi9TOpzj7WVQNCviT1g%3D%3D"
Url = `https://www.zhipin.com/c100010000/?query=web&page=1`
Cookies = `Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a="1571451828";Hm_lvt_194df3105ad7148dcf2b98a91b5e727a="1571459326,1571405292";__zp_stoken__="9a3dBF3MCmyPZ4Zs9eRYGXGURUgs3h8Pz03%2FrBtAtNgB67REb52tBBbLpjxcmw7ZppohumsjJF79M4BFI5NcaRf4uw%3D%3D";__a="87719411.1571405292.1571405292.1571451826.31.2.13.31";__l="l=%2Fwww.zhipin.com%2Fweb%2Fcommon%2Fsecurity-check.html%3Fseed%3Dhh1Zsbm2A%252F%252BeXJf4gqJS9CbEi5ue7LIi93osZZEXcbQ%253D%26name%3D9205702c%26ts%3D1571451825250%26callbackUrl%3D%252Fc101010100%252F%253Fquery%253Dweb%2525E5%252589%25258D%2525E7%2525AB%2525AF%2526industry%253D%2526position%253D%2526ka%253Dhot-position-4%26srcReferer%3D&r=&friend_source=0&friend_source=0";__c="1571451826";__g="-";lastCity="101010100";`
PyCookie = `__a=87719411.1571405292.1571571431.1571573191.78.4.13.78;__c=1571573191;__g=-;__l=l=%2Fwww.zhipin.com%2F&r=https%3A%2F%2Fwww.google.com%2F&friend_source=0&friend_source=0;__zp_stoken__=ab17gAKyCiVPXoKZouYVWxVmXuy2kQJQJ%2F6uuhUOaDa%2BRZ9ZvxqNAl4vkQlWuQeuD8AI2%2BFzigw0Rn8u8aG0SRQwTQ%3D%3D;Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1571573763;Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1571400558,1571451828,1571571431,1571573191;lastCity=101010100;`
WebCookie = `__a=87719411.1571405292.1571571431.1571573191.96.4.31.96;__c=1571573191;__g=-;__l=l=%2Fwww.zhipin.com%2F&r=https%3A%2F%2Fwww.google.com%2F&friend_source=0&friend_source=0;__zp_stoken__=ab17gAKyCiVPXoKZouYVWxVmXs0qmerbaXOj2SvOTZ3F0nykSLMt6yXjKQvmT6cRx9D0lX6rj9G1mFFcm7bmxmRuzA%3D%3D;Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1571581244;Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1571400558,1571451828,1571571431,1571573191;lastCity=101010100;`
Dir = "C:/Users/12161/Desktop/env_m/go/src/apiserver/GOspider/BossZhiPin/"
UserAgentList = []string{"Mozilla/5.0 (compatible, MSIE 10.0, Windows NT, DigExt)",
"Mozilla/4.0 (compatible, MSIE 7.0, Windows NT 5.1, 360SE)",
"Mozilla/4.0 (compatible, MSIE 8.0, Windows NT 6.0, Trident/4.0)",
"Mozilla/5.0 (compatible, MSIE 9.0, Windows NT 6.1, Trident/5.0,",
"Opera/9.80 (Windows NT 6.1, U, en) Presto/2.8.131 Version/11.11",
"Mozilla/4.0 (compatible, MSIE 7.0, Windows NT 5.1, TencentTraveler 4.0)",
"Mozilla/5.0 (Windows, U, Windows NT 6.1, en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (Macintosh, Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
"Mozilla/5.0 (Macintosh, U, Intel Mac OS X 10_6_8, en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (Linux, U, Android 3.0, en-us, Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13",
"Mozilla/5.0 (iPad, U, CPU OS 4_3_3 like Mac OS X, en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
"Mozilla/4.0 (compatible, MSIE 7.0, Windows NT 5.1, Trident/4.0, SE 2.X MetaSr 1.0, SE 2.X MetaSr 1.0, .NET CLR 2.0.50727, SE 2.X MetaSr 1.0)",
"Mozilla/5.0 (iPhone, U, CPU iPhone OS 4_3_3 like Mac OS X, en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
"MQQBrowser/26 Mozilla/5.0 (Linux, U, Android 2.3.7, zh-cn, MB200 Build/GRJ22, CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"}
)
//从上面列表中获取一个User-Agent
func GetRandomUserAgent() string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
return UserAgentList[r.Intn(len(UserAgentList))]
}
// 下载基础的html
func GetBaseHtml(url string, dir string ,cookies string) (err error) {
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Cookie", cookies)
req.Header.Add("User-Agent", GetRandomUserAgent())
req.Header.Add("Accept", "*/*")
req.Header.Add("Cache-Control", "no-cache")
req.Header.Add("Postman-Token", "6de4691b-9ff1-49f1-b702-e1af878a8941,33aac300-f20d-4e5c-b3f2-99977fc88286")
req.Header.Add("Host", "www.zhipin.com")
req.Header.Add("Accept-Encoding", "text/html")
req.Header.Add("Connection", "keep-alive")
req.Header.Add("cache-control", "no-cache")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
err = ioutil.WriteFile(dir, body, 0644)
<-time.After(time.Second*2)
return err
}
// 得到一批html文件
func mainGetBaseHtml(n int ,cookies string){
for i:=1;i<n+1; i++{
url := Url + strconv.Itoa(i)
dir_info := Dir + strconv.Itoa(1000+i)+".html"
err := GetBaseHtml(url, dir_info,cookies)
if err !=nil{
log.Fatal(err)
}
fmt.Println("di --- " ,i)
}
}
3、根据返回的数据进行数据处理
...
// 获取页面信息切片 这里分析页面了html结构,根据标签class选择关键字
func GetHtmlSlice(Dir string) (Ctt []CompanyStruct) {
f, err := os.Open(Dir)
if err != nil {
log.Fatal(err)
}
defer f.Close()
doc, err := goquery.NewDocumentFromReader(f)
if err != nil {
log.Fatal(err)
}
// use the goquery document...
doc.Find(".job-primary").Each(func(i int, cs *goquery.Selection) {
companyStruct := CompanyStruct{}
cs.Find(".info-primary").Each(func(i1 int, cs1 *goquery.Selection){
text := cs1.Find(".job-title").Text()
companyStruct.JobType=text
s := cs1.Find(".red").Text()
companyStruct.Mania=s
i2 := cs1.Find("p").Text()
companyStruct.InLand=i2
})
cs.Find(".info-company").Each(func(i1 int, cs1 *goquery.Selection){
company1 := cs1.Find("h3 a").Text()
i2 := cs1.Find("p").Text()
companyStruct.ForCompany=company1
companyStruct.CompanyInfo=i2
})
cs.Find(".info-publis").Each(func(i1 int, cs1 *goquery.Selection){
text := cs1.Find("h3").Text()
companyStruct.JobLind=text
})
structs := append(Ctt, companyStruct)
Ctt = structs
})
return Ctt
}
4、数据处理后存储
...
//解析切片数据存入redis 省略
//解析切片存入mysql
func mainSetMysql(n int){
db, err := sqlx.Open("mysql", "root:123123@tcp(192.168.1.196:3306)/Spider")
if err !=nil{
db.Close()
log.Fatal(`sqlx.Open("mysql", "root:123123@tcp(192.168.1.196:3306)/Spider")`)}
for i:=1;i<n+1; i++ {
dir_info := Dir + strconv.Itoa(1000+i) + ".html"
Ctt := GetHtmlSlice(dir_info)
for _,v:= range Ctt{
var(joblind = v.JobLind
cominfo = v.CompanyInfo
jobtype=v.JobType
forcompany=v.ForCompany
inland=v.InLand
mania=v.Mania)
result, err := db.Exec("insert into Spider.boosszhipin(招聘者, 公司信息, 工作类型, 招聘公司, 在何地招聘, 薪资范畴) values (?,?,?,?,?,?)", joblind, cominfo, jobtype, forcompany, inland, mania)
if err!=nil{ log.Fatal(`"db.Exec("insert into Spider.boosszhipin(招聘者, 公司信息, 工作类型, 招聘公司, 在何地..."`,err)}
fmt.Println(result.LastInsertId())
}
}
}
func main(){
//mainGetBaseHtml(10,WebCookie)
//mainSetRidsData(5)
mainSetMysql(12)
}
5、数据展示
...
*************************** 206. row ***************************
id: 206
招聘者: 任先生招聘者
公司信息: 计算机服务不需要融资0-20人
工作类型: web前端
招聘公司: 驰宇科技
在何地招聘: 石家庄 经验不限大专
薪资范畴: 2-5K
*************************** 207. row ***************************
id: 207
招聘者: 林先生招聘者
公司信息: 互联网已上市10000人以上
工作类型: web 前端开发工程师
招聘公司: 好未来
在何地招聘: 深圳 南山区 科技园3-5年本科
薪资范畴: 15-30K
*************************** 208. row ***************************
id: 208
招聘者: 梁先生人事
公司信息: 互联网天使轮20-99人
工作类型: Web前端
招聘公司: 安徽九广全景科技
在何地招聘: 合肥 1-3年大专
薪资范畴: 7-8K
*************************** 209. row ***************************
id: 209
招聘者: 刘先生IT技术架构
公司信息: 通信/网络设备已上市10000人以上
工作类型: Web前端工程师
招聘公司: 中兴通讯股份有限公司
在何地招聘: 长沙 岳麓区 麓谷西3-5年本科
薪资范畴: 9-14K·14薪
209 rows in set (0.00 sec)
MariaDB [Spider]>
MariaDB [Spider]> select 招聘者,在何地招聘,工作类型,薪资范畴 from boosszhipin;
+---------------------------------------------+----------------------------------------------------+-----------------------------------------+---------------+
| 招聘者 | 在何地招聘 | 工作类型 | 薪资范畴 |
+---------------------------------------------+----------------------------------------------------+-----------------------------------------+---------------+
| 常先生高级软件工程师 | 西安 3-5年本科 | Python | 15-30K |
| 郭女士招聘者 | 东莞 1-3年本科 | Python | 8-13K |
| 谢先生招聘专员 | 东莞 经验不限本科 | Python | 9-13K |
| 付女士人事 | 长沙 岳麓区 麓谷3-5年大专 | python | 10-15K |
| 高女士HR | 杭州 滨江区 长河1-3年本科 | Python | 10-15K |
| 李女士HR | 西安 长安区 王寺3-5年本科 | Python | 9-14K |
| 杨先生招聘者 | 成都 金牛区 中海国际3-5年大专 | Python导师 | 15-30K |
| 李女士招聘主管 | 北京 东城区 磁器口5-10年本科 | Python讲师 | 15-30K |
| 侯女士招聘 经理 | 天津 东丽区 军粮城5-10年本科 | python | 10-15K |
| 开发 | 武汉 江夏区 光谷东3-5年本科 | Python | 15-30K·14薪 |
| 巩先生运维经理 | 南京 雨花台区 宁南3-5年本科 | Python | 15-30K |
总结
反扒策略不止于此,不解决反扒策略考虑多协程也没用。