(图片来源于网络)
首先,作为一个刚入门python的小白,可以跟大家说,使用爬虫其实并不是很难。但是深入学习就另说了。
要使用python爬虫,首先要知道爬虫是什么?能做什么?先来一波百度:
网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。爬虫可以抓取网络上的数据。爬虫可以用很多种编程语言实现,python只是一种。所以你想知道的是网络爬虫可以干什么。他比如证券交易数据,天气数据,网站用户数据,图片。拿到这些数据之后你就可以做下一步工作了。(附上百度百科链接:http://baike.baidu.com/view/284853.htm)
我们开始着手编写一个简单的python爬虫:
一、准备工作
1.预备知识:
Python3.x基础知识学习:
可以在通过如下方式进行学习:
(1)廖雪峰Python3教程(文档):
URL:http://www.liaoxuefeng.com/
(2)菜鸟教程Python3教程(文档):
URL:http://www.runoob.com/python3/python3-tutorial.html
(3)鱼C工作室Python教程(视频):
小甲鱼老师很厉害,讲课风格幽默诙谐,如果时间充裕可以考虑看视频。
Python版本:3.X(到官网下载安装)
其实只要掌握Python的基本语法和一些常用的系统函数,基本上就可以了,后期可以在实践中不断学习。
2.预备工具:
pip安装工具
pip 是一个安装和管理 Python 包的工具,python安装包的工具有easy_install, setuptools, pip,distribute。使用这些工具都能下载并安装django。,而pip是easy_install的替代品。在CPython解释器,pypy解释器,可以很好地工作。(只要不是版本过早的python,pip都是系统自带的)
cmd命令行输入指令:
pip
出现以下页面则表示pip已经安装了。
Q:如果不将pip更新到最新版本,可能会安装失败,那如何将pip更新到最新版本?
A:只用使用命令如下就可以更新了。
python -m pip install --upgrade pip
Requests 模块
启动cmd命令行->输入命令:(前提是已经安装好python)
pip install requests
(这是已经安装完成的样子)
附上requests使用手册:
URL:http://docs.python-requests.org/zh_CN/latest/user/quickstart.html
BeautifulSoup4模块
输入命令:
pip install BeautifulSoup4
(这是已经安装完成的样子)
附上BeautifulSoup4使用手册:
URL:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html
叫我雷锋,不用谢~
最后,安装完可以进行检测,调用 一下:
(不报错则安装成功)
至于开发工具,我用的是: jupyter notebook 也是可以通过pip下载的一个编辑器,看个人喜欢可以用其他的编辑器进行实验。
二、编写简单的python爬虫
我们以某东购物网站为例:
比如,现在我想收集一下一些产品的报价行情是怎样的。
第一步:就是要确定什么样的数据对我们来说是有用的
- 价格
- 产品名称
- 销售地区
- 销售量
第二步:分析网页结构
1.简单点,先进行条件筛选
2.通过开发者工具找到网页的请求信息
主要的两个数据是:
Request URL 和 Request Method
3.寻找所需数据的HTML信息
以价格为例:
通过开发者工具我们可以发现这是一个循环体:
然后开始打代码:
1)先获得URL的资源:
import requests
url = 'Request URL' #这里的URL就是通过开发者工具找到的网页的请求信息里的Request URL
res = requests.get(url) #requests后面的方法要根据网页的请求信息来判断
res.encoding='utf-8' #可加可不加,爬虫结果乱码,可以用这个代码更正
print(res.text) #输出获取到的东西
如果成功则会返回这样的信息:
注意:这里面使用requests的get方法来获取html,具体是get还是post等等要通过网页头信息来查询:
2)将得到的网页利用BeautifulSoup进行剖析
import requests
from bs4 import BeautifulSoup
url = 'https://list.jd.com/list.html?cat=670%2C671%2C672&go=0'
res = requests.get(url)
res.encoding = 'utf-8'
soup = BeautifulSoup(res.text,"html5lib")
print(soup.select('.J_price'))
下面高能请注意!!!
作为一个小白,这个问题真的是难到我了,爬出来的都是空值。。。
明明我之前去爬他家的资源的时候还是这样的:
黑人问号脸。。。???
我然后用搜索的方式搜索了一些产品,还完善了一下代码,发现又可以爬出来数据:
附上源代码:
import requests
from bs4 import BeautifulSoup
url = 'https://search.jd.com/search?keyword=%E8%81%94%E6%83%B3%E6%8B%AF%E6%95%91%E8%80%85&enc=utf-8&qrst=1&rt=1&stop=1&spm=a.0.0&vt=2&bs=1&ev=exbrand_%E8%81%94%E6%83%B3%EF%BC%88Lenovo%EF%BC%89%5E&cid3=672'
res = requests.get(url)
res.encoding='utf-8'
soup = BeautifulSoup(res.text,"html5lib")
for item in soup.select(".gl-item"):
try:
print(item.select("i")[0].text,item.select("em")[1].text)
for item2 in item.select("span.J_im_icon"):
print(item2.select("a")[0].text)
except OSError:
pass
continue
辗转反侧一晚上,程序员小白的常规操作,然后我万能的票圈的到了我想要的答复。
出现这样的问题是因为一些数据是异步请求出来的,在这里我要先附上点AJAX的知识:
AJAX
- :
Asynchronous JavaScript and XML
- (异步的
JavaScript
- 和
XML
- )。它不是新的编程语言,而是一种使用现有标准的新方法。它采用的是
AJAX
- 异步请求。通过在后台与服务器进行少量数据交换,
AJAX
XHR
- :
XMLHttpRequest
- 什么是异步加载?
向网站进行一次请求,一次只传部分数据。如:有些网页不需要点击下一页,其内容也可以源源不断地加载。 - 如何发现异步加载?
1、打开浏览器,右键选择“检查”
2、点击“Network”、“XHR”
这样在网页进行不断下拉的过程中,显示器会记录全部动作。可以看到不断加载新的页。
三、编写python异步爬虫
我找了很多资料,然后自己总结的话就是,用爬虫去爬取数据的时候,有时候会出现服务器反爬虫的防御出现(淘宝就有),返回的数据就是空值,那么这时,就要爬虫带着点数据,伪装得像一个人在访问他们的服务器去爬取数据。比如:在招聘网站拉勾网【网站链接】中爬出Python
相关职位的一些基本信息(那些大公司的网站太复杂,我作为一个小白还是低调点好了。。。)
1.分析网页
打开拉勾网主页之后,我们在搜索框中输入关键字Python
,以用来查找和Python
相关的职位。在搜索结果的页面中,我们按照以下顺序操作可以发现。–> 右键检查
–> 打开审查元素后默认打开的是Elements
–> 我们切换到Network
标签,刷新一下网页会出现各种条目的请求
–> 因为该网站是异步请求,所以打开Network
中的XHR
,针对JSON
中的数据进行分析。
–> 在审查元素中我们可以发现以下信息:
# 该页面的请求url
Request URL:https://www.lagou.com/jobs/positionAjax.json?city=%E5%B9%BF%E5%B7%9E&needAddtionalResult=false&isSchoolJob=0
# 该页面的请求方法,需要提交表单数据(Form-data)
Request Method:POST
Form-data: first: true
pn: 1
kd: python
--------------------------------
# Request Headers中的相关信息
包括Cookie、Referer、User-Agent等我们之后会用到的信息
附上源代码:
import requests # 导入请求模块
url = 'https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E6%88%90%E9%83%BD&needAddtionalResult=false&isSchoolJob=0'
form_data = {'first': 'true',
'pn': '1',
'kd': 'python'}
def getJobList():
res = requests.post(
# 请求url
url=url,
# 填写表单数据
data = form_data
)
result = res.json() # 获取res中的json信息
print(result)
getJobList()
运行结果:
{'success': False, 'msg': '您操作太频繁,请稍后再访问', 'clientIp': '183.234.123.115'}
出现这样他的结果,应该是拉钩网的反爬机制起了作用,所以此时就需要伪装成用户去访问,需要加入headers
信息。
附上源代码:
import requests
url = 'https://www.lagou.com/jobs/companyAjax.json?city=%E6%B7%B1%E5%9C%B3&needAddtionalResult=false'
form_data = {'first': 'true',
'pn': '1',
'kd': 'python'}
HEADERS = {
# User-Agent(UA) 服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。也就是说伪装成浏览器进行访问
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36',
# 用于告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理。如果不加入,服务器可能依旧会判断为非法请求
'Referer': 'https://www.lagou.com/zhaopin/Python/?labelWords=label'}
def getJobs():
res = requests.post(url=url, headers=HEADERS, data=form_data)
result = res.json()
print(result)
getJobs()
运行结果:
{'success': True, 'requestId': None, 'resubmitToken': None, 'msg': None, 'code': 0, 'content': {'pageNo': 1, 'pageSize': 15, 'totalCount': 0, 'hasNextPage': False, 'totalPageCount': 0, 'currentPageNo': 1, 'hasPreviousPage': False, 'result': [], 'start': 0}}
这样就获得了响应结果中的json
信息,它和Preview
中的数据信息是一致的(dict
类型顺序可能不一致)。
然后就爬他的数据
附上源代码:
import requests
url = 'https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E6%B7%B1%E5%9C%B3&district=%E5%8D%97%E5%B1%B1%E5%8C%BA&needAddtionalResult=false&isSchoolJob=1'
HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
'Referer': 'https://www.lagou.com/jobs/list_Python?px=default&gx=&isSchoolJob=1&city=%E6%B7%B1%E5%9C%B3&district=%E5%8D%97%E5%B1%B1%E5%8C%BA'
}
form_data = {'first': 'true',
'pn': '1',
'kd': 'python'}
def getJobs():
res = requests.post(url=url, headers=HEADERS, data=form_data)
result = res.json()
jobs = result['content']['positionResult']['result']
return jobs
for job in getJobs():
# 这里演示,提取出公司地址+名称+公司优势+工资待遇
print(job['district'] + ':' + job['companyFullName'] + ':' + job['positionAdvantage'] + ':' + job['salary'])
运行结果:
注意:print()输出的是string类型的值,一定要把JSON格式的list爬到最底层的数据再输出,不能输出list类型的数据。
爬完数据后可以手动也可以进一步用python的其他模块的功能,将数据整理并存储起来供自己使用(不能触犯法律噢)
四、总结
忙活一段时间,还是发现python爬虫其实不简单,没有点web开发的基本功,那么这个爬虫还是爬不到很多东西的。
爬取异步数据的时候没有用到BeautifulSoup4模块的功能,因为bs4是对DOM进行操作的一个功能模块,感觉限制还是很多的,他不能脱离HTML代码进行操作。而相对的requests模块的功能比较强大且复杂,对于数据有更好的爬取能力。python爬虫并不只有这两个东东能实现,还有urllib、BaseSpider、sitemap等,还有一些框架也很方便实现爬虫功能,在实现爬虫功能的同时,又需要很多其他的模块来进行辅助,Json库包就可以实现一些JSON格式数据的处理。
爬取人家的数据还要破解人家的密钥,对于现在的我来说最多也就只能看看,懂多少也不敢说,不过学习就是这样,现在不懂的东西但是它是已经存在的了,人家能写出来就说明我的学习还是不到家的。虽然这是一份作业,但是我也学到了不少东西。
我是一个python小白,我以这样的方式来记录我的学习与进步,不管能不能成功,至少我努力地去学习了。(゜-゜)つロ 干杯~
(图片来源于网络)
=======================================================================
- The End -
作者 | JM.Zack