Python 爬虫入门-爬取拉勾网实战

这几天学习了 python 爬虫的入门知识,也遇到很多坑,开个贴记录一下


基本原理


Python 爬虫基本要具备以下功能:(参考此回答

  1. 向服务器发送请求,服务器响应你的请求。(你可能需要了解:网页的基本知识)
  2. 从抓取到的网页中提取出需要的数据。(你可能需要了解:正则表达式Beautifulsoup
  3. 保存数据并继续爬取下一个网站。

    当然,有以上功能还是不够的,你还需要与网站反爬策略斗智斗勇:(参考此回答

    1. 构造合理的HTTP请求头
    2. 设置cookie
    3. 正常的时间访问路径
    4. 注意隐含输入字段值
    5. 避开蜜罐
    6. 使用远程服务器来避免IP封锁

当然以上我还不怎么会。


项目实践

可以通过以下2个项目练手

  1. 豆瓣电影TOP250
    这个项目比较容易,代码复制过来,大概理解代码的意思,然后跑的过程也比较顺利。

  2. 爬取拉勾网页面1 页面2 页面3
    这个项目就比较难了,我也遇到比较多的坑,好在大都解决了。

话不多说,我们开始吧

爬取拉勾网实战

借用一下@ _知几 的图

借用一下@ _知几 的图,按 F12 查看页面源码,在 NETWORK 标签中可以分析网站的请求响应过程,这里看到 NETWORK 标签下 TYPE XHR 里有 companyAjax.json 和 positionAjax.json (开始我死活找不到positionAjax.json,后来发现是我没选工作地点),我们所需求的数据可以从中提取出来。


以下代码是我在 _知己 的代码基础上修改得到的

修改了以下几处:

  1. 由原来的 python 2 改为 python 3
  2. 导入 fake_useragent 模块,可以随机伪造请求头(使用前需 pip install fake-useragent)
  3. 读取 companyAjax.json 而不是原来的 positionAjax.json

几点说明:

  1. ua.random 用于生成随机请求头
  2. get_json 函数中的 my_headers、 cookies、 content 等,都可以在浏览器 F12 控制台中找到
  3. 目前爬取了几页后就被发现,显示 {‘success’: False, ‘msg’: ‘您操作太频繁,请稍后再访问’, ‘clientIp’: ‘202. ‘},暂时还没有解决办法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/usr/bin/env python
# encoding=utf-8
import json
import requests
import xlwt
import time
from lxml import etree
import random
from fake_useragent import UserAgent
import sys
#获取存储职位信息的json对象,遍历获得公司名、福利待遇、工作地点、学历要求、工作类型、发布时间、职位名称、薪资、工作年限
def get_json(url,datas):
ua = UserAgent()
my_headers = {
'User-Agent': ua.random ,
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.6,ja;q=0.4,en;q=0.2',
'Host': 'www.lagou.com',
'Origin': 'https://www.lagou.com',
'Referer': 'https://www.lagou.com/zhaopin/?filterOption=',
}
cookies = {
'Cookie': 'user_trace_token=20170824135842-485287de-8891-11e7-a544-525400f775ce; LGUID=20170824135842-48528e05-8891-11e7-a544-525400f775ce; JSESSIONID=ABAAABAAADEAAFI772FD1B9AABBF0C5553E874B0F860350; _putrc=B95D7C5E94F53DA8; login=true; unick=%E9%83%AD%E5%B2%A9; showExpriedIndex=1; showExpriedCompanyHome=1; showExpriedMyPublish=1; hasDeliver=3; PRE_UTM=; PRE_HOST=; PRE_SITE=; PRE_LAND=https%3A%2F%2Fwww.lagou.com%2F; _gat=1; TG-TRACK-CODE=index_search; SEARCH_ID=f0acbb8b2145433cb8fe7086f23be622; index_location_city=%E5%8C%97%E4%BA%AC; _gid=GA1.2.397092414.1504747009; Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1504756944,1504761486,1504783443,1504839029; Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1504839719; _ga=GA1.2.1499897355.1503554319; LGSID=20170908105032-7b45520c-9440-11e7-8aae-525400f775ce; LGRID=20170908110159-14c6e1a8-9442-11e7-8ab1-525400f775ce'
}
time.sleep(20 + random.randint(0,20))
content = requests.post(url=url,cookies=cookies,headers=my_headers,data=datas)
# content.encoding = 'utf-8'
result = content.json()
print(result)
info = result['content']['positionResult']['result']
# print info
info_list = []
for job in info:
information = []
information.append(job['positionId']) #岗位对应ID
information.append(job['companyFullName']) #公司全名
information.append(job['companyLabelList']) #福利待遇
information.append(job['district']) #工作地点
information.append(job['education']) #学历要求
information.append(job['firstType']) #工作类型
information.append(job['formatCreateTime']) #发布时间
information.append(job['positionName']) #职位名称
information.append(job['salary']) #薪资
information.append(job['workYear']) #工作年限
info_list.append(information)
#将列表对象进行json格式的编码转换,其中indent参数设置缩进值为2
print(json.dumps(info_list,ensure_ascii=False,indent=2))
print(info_list)
return info_list
def main():
page = int(input('输入抓取页数:'))
# kd = raw_input('请输入你要抓取的职位关键字:')
# city = raw_input('请输入你要抓取的城市:')
info_result = []
title = ['岗位id','公司全名','福利待遇','工作地点','学历要求','工作类型','发布时间','职位名称','薪资','工作年限']
info_result.append(title)
for x in range(1,page+1):
url = 'https://www.lagou.com/jobs/companyAjax.json?px=new&needAddtionalResult=false'
datas = {
'first': True,
'pn': x,
'kd': '',
#'city': '上海'
}
info = get_json(url,datas)
info_result = info_result+info
#创建workbook,即excel
workbook = xlwt.Workbook(encoding='utf-8')
#创建表,第二参数用于确认同一个cell单元是否可以重设值
worksheet = workbook.add_sheet('lagouzp',cell_overwrite_ok=True)
for i, row in enumerate(info_result):
# print row
for j,col in enumerate(row):
# print col
worksheet.write(i,j,col)
workbook.save('C:\\Users\\jared\\Desktop\\lagouzp.xls')
if __name__ == '__main__':
main()

本文标题:Python 爬虫入门-爬取拉勾网实战

文章作者:微石

发布时间:2017年10月11日 - 15:10

最后更新:2018年07月19日 - 11:07

原始链接:akihoo.github.io/posts/ddfdbfd2.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。