一般小型的爬虫需求,直接使用requests库 + bs4就解决了, 再麻烦点就使用selenium解决js的异步加载问题(数据不直接在网站中,而是通过JS异步渲染,也是反爬技术之一),利用IPProxys 设置ip代理池。比较大型的需求才使用框架Scrapy,主要是便于管理以及扩展等。
Requests。是用python语言基于urllib编写的,requests库进一步封装了urllib3, 采用的是Apache2 Licensed开源协议的HTTP库,可用于发出互联网请求并获取返回信息,比起urllib包的繁琐,requests库特别简洁和容易理解。快速上手request
bs4全名BeautifulSoup,是编写python爬虫常用库之一,主要用来解析html标签。
bs4使用selenium。这是一个调用浏览器的driver,通过这个库你可以直接调用浏览器完成某些操作,比如输入验证码。
selenium已经放弃PhantomJS,了,建议使用火狐或者谷歌无界面浏览器。Scrapy 一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。
如果想走爬虫工程师方向的小伙伴建议系统的学习Scrapy进行科学合理的爬虫开发, 而本人是想要走WEB后端路线,之后的重点也在Django,所以粗略的学习一下简单爬虫的编写和反扒技术平时作一项技能来打游击。IPProxys 反爬技术开源项目之一 爬取一些代理网站提供的免费ip(虽然70%都是不好使的,但是扛不住量大,网站多),检测有效性后存储到数据库中,同时搭建一个http服务器,提供一个api接口,供大家的爬虫程序调用
开源文章参考tesserorc Python的一个OCR库,但其实是对tesseract做的一层Python APIde 封装,所以他的核心是tesseract。因此,在安装tesserocr之前,我们需要先安装tesseract,这里使用它来进行验证码图片的OCR识别。
tesserorc安装和使用
爬虫遇到问题
网页编码
Requests 会自动解码来自服务器的内容。大多数 unicode 字符集都能被无缝地解码。
请求发出后,Requests 会基于 HTTP 头部对响应的编码作出有根据的推测。
当你访问 r.text 之时,Requests 会使用其推测的文本编码。
你可以找出 Requests 使用了什么编码,并且能够使用 r.encoding 属性来改变它:
r.encoding = 'gbk'
print(r.text)
反爬技术与爬虫技术
A. UserAgent 设置用户代理--基于request类实现
User-Agent是检查用户所用客户端的种类和版本。通过设置UA可以伪装成浏览器进行访问目标网站
headers = {'User-Agent': 'Mozilla/4.0(compatible; MSIE 8.0; Windows NT 6.0'}
r = requests.post(
'https://api.github.com/events',
headers=headers)
B.携带cookie--基于request类实现
首先使用post表单提交模拟登陆一次
然后使用r.cookies['example_cookie_name']获取cookie并加入之后的请求头
headers = {
'User-Agent': 'Mozilla/4.0(compatible; MSIE 8.0; Windows NT 6.0',
"Cookie": 'Pycharm-26c2d973=dbb9b300-2483-478f-9f5a-16ca4580177;'
}
r = requests.post(
'https://api.github.com/events',
headers=headers)
另外,使用cookies参数接收字典形式的cookie
cookies的形式:字典
cookies = {"cookie的name":"cookie的value"}
使用方法:
requests.get(url,headers=headers,cookies=cookie_dict}
C.代理ip和ip池---从IPProxys 获取代理ip池源
---request设置代理ip方法
要设置什么代理ip可以去网站查得
proxies = {'http': 'http://localhost:8888', 'https': 'http://localhost:8888'}
有时候代理ip需要使用HTTP basic Auth
格式为: 'http': '用户名:密码@ip:port'
r = requests.post(
'https://api.github.com/events',
proxies=proxies)
---从IPProxys 动态获取代理ip池源
这个模块我配置失败了, 正在研究,之后更新,虽然目前只是使用静态代理ip池就足够了
D. 验证码
爬虫运行一段时间后,会遇到针对一组ip进行验证码限制的情况此处又分滑动验证码和填写验证码。
针对填写验证码
通用的方法是, 将验证码下载下来,通过python图片OCR识别库来分析验证码。
此处选择使用tesserorc进行OCR识别针对滑动验证码,使用seelenium暴力破解
参考
E. 使用selenium库获取js异步动态加载的数据
这个模块比较难, 正在研究,之后更新
基于bs4的爬虫数据提取
初级数据解析时使用lxml库的etree针对xml或html进行解析, 然后编写xpath或正则表达式提取信息。
其实bs库最根本的就是帮助我们封装好了常见针对html的正则或xpath方便我们直接调用。
bs4的四大对象种类
- 标签
- NavigableString
- BeautifulSoup
- 评论
1、标签Tag
Tag通俗点讲就是HTML中的一个个标签,例如:title head
可以使用bs4直接获取
soup.title
soup.head
soup.a
对于Tag,它有两个重要的属性,是name
和attrs
print soup.head.name
# head #对于其他内部标签,输出的值便为标签本身的名称
print soup.p.attrs
# {'class': ['title'], 'name': 'dromouse'}
# 在这里,我们把 p 标签的所有属性打印输出了出来,得到的类型是一个字典。
soup.p.get('class') # soup.p.['class'] 等价的
# 使用get方法, 或[]索引可以针对某个属性获取和更改
2、NavigableString
既然我们已经得到了标签的内容,那么问题来了,我们要想获取标签内部的文字怎么办呢?很简单,用.string即可,例如
NavigableString 对象包含在一个页面元素内。只有最高层的剖析对象和 Tag 对象有contents。 NavigableString 只有strings,不能包含子元素,因此他们也没有contents。
print soup.p.string
# The Dormouse's story
3、BeautifulSoup
BeautifulSoup对象表示的是一个文档的内容。大部分时候,可以把它当作Tag对象,是一个特殊的Tag,我们可以分别获取它的类型,名称,以及属性来感受一下
# 得到一个 BeautifulSoup 的对象,并能按照标准的缩进格式的结构输出。
soup = BeautifulSoup(html_doc, 'html.parser')
soup.name
soup.title
4、注释及特殊字符串(Comment)
Tag , NavigableString , BeautifulSoup 几乎覆盖了html和xml中的所有内容,但是还有一些特殊对象.容易让人担心的内容是文档的注释部分。
Comment对象是一个特殊类型的NavigableString对象:
可以用获取NavigableString的方法获取comment
comment = soup.b.string
type(comment)
>>> <class 'bs4.element.Comment'>
# # 获取html注释内容
soup.b.prettify()
# 声明XML对象中可能出现的属性并获取CData , ProcessingInstruction , Declaration , Doctype
from bs4 import CData
cdata = CData("A CDATA block")
comment.replace_with(cdata)
几个常用提取信息工具的比较:
- 正则:很快,不好用,不许安装
- beautifulsoup:慢,使用简单,安装简单
- lxmL:比较快,使用简单,安装一般
Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装。
下面是在bs中使用其他解析器的用法
推荐使用lxml作为解析器,因为效率更高. 在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib, 因为那些Python版本的标准库中内置的HTML解析方法不够稳定。