嘿嘿,一直想要启动的爬虫学习今个终于开始了。计划花费一到两个月的时间把基本的爬虫类型都尝试一遍。按照某某公司的实习要求开始一步步的学习着~~
第一步: 了解request和response
1、何为Request
浏览器访问一个网站需要先该网站发送一个请求,请求包括两个部分,请求头和请求体。在请求头中包含method,url,content-type,cookie,Referer,User-Agent
等信息。请求体则是浏览器在请求是要向服务器发送的信息,比如提交的表单数据,上传的文件等等。在爬虫中cookie、referer,user-agent
这些header
信息是比较常用的,有的网站必须要带着cookie
才能正常访问。有的存在反盗链的就需要referer
,其他情况的还没遇到。
2、何为Response
服务器在接受到客户端的请求后会检测请求中的信息,判断请求是否合法,服务器中是否存在相对应的资源。如果验证通过,服务器会向客户端返回一个响应。一个响应也存在两个部分,响应头和响应体。在响应头中包含对响应文件类型的描述Content-Type
,响应状态码(200,、404、301、502等)
,产生响应的时间Date
,还有一个比较重要的Set-Cookie
和其他我还不了解具体用途的等等、、、重点在响应体,这里就是客户端想要获取的内容了。有可能是一个html
文档,也可能是json/xml
数据,文件等。
第二步: 熟悉python中的基本库
1、比较基础的urllib
库
这个库是python中自带的网络请求库,对于一些简单的请求还是可以应付的,复杂点的用起来就比较费事了。简单记录下我所掌握的。
#发送一个get请求
res = urllib.urlopen('http://httpbin.org/get')
print res.read()
#使用构造Request的方式
request = urllib2.Request('http://httpbin.org/get')
res = urllib2.urlopen(request)
print res.read()
# 发送一个post请求,并上传表单数据
fd = {
'name': 'lucy'
}
data = urllib.urlencode(fd)
url = 'http://httpbin.org/post'
request = urllib2.Request(url, data)
res = urllib2.urlopen(request)
print res.read()
# 设置header,在构造的request中传入一个字典就行
fd = {
'name': 'lucy'
}
data = urllib.urlencode(fd)
url = 'http://httpbin.org/post'
request = urllib2.Request(url, data, headers={'cookie': 'lllllll'})
res = urllib2.urlopen(request)
print res.read()
## 还有设置代理,使用CookieJar构造cookie等,不太熟练。
2、正则表达式re
库
共有如下常用方法:
def match(pattern, string, flags=0) 匹配字符串,匹配到结果则返回一个match对象,否则None
def search(pattern, string, flags=0) 在字符串中搜索,搜索到返回一个match对象,否则None
def sub(pattern, repl, string, count=0, flags=0) 匹配到指定规则的字符串,就用repl替换掉,返回替换后的字符串,count替换次数,默认0所有
def split(pattern, string, maxsplit=0, flags=0) 匹配正则中的字符用来分割字符串
def findall(pattern, string, flags=0) 从字符串中获取匹配到的内容并作为一个列表返回
def finditer(pattern, string, flags=0) 从字符串中获取匹配到的内容并作为一个迭代器返回
def compile(pattern, flags=0) 用来生成一个正则规则
其中最后一个参数flags用来指定正则匹配模式,可以写多个用|
分割
• re.I(全拼:IGNORECASE): 忽略大小写(括号内是完整写法,下同)
• re.M(全拼:MULTILINE): 多行模式,改变'^'和'$'的行为
• re.S(全拼:DOTALL): 点任意匹配模式,改变'.'的行为,既可以匹配所有字符
• re.L(全拼:LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
• re.U(全拼:UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
• re.X(全拼:VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。
第三步:使用requests
库代替urllib
进行网络请求
这个请求库可谓是十分地强大了,而且提供的api还足够的方便简洁,简单的使用下。
# 进行一个get请求
res = requests.get('http://httpbin.org/get')
print res.text
# 进行一个post请求,并提交表单,上传文件
# 多么的简洁,这在urllib中如果实现是相当麻烦,我是记不住怎么弄
payload = {
'key1': 'value1', 'key2': 'value2'
}
files = {
'mmtu': open('D:/04.jpg', 'rb')
}
res = requests.post('http://httpbin.org/post', data=payload, files=files)
print res.text
# 设置header,cookie,并下载图片
headers = {
'Referer': 'http://www.mzitu.com/'
}
cookies = {
'ck': 'opopop'
}
res = requests.get('http://i.meizitu.net/2018/02/26c15.jpg', headers=headers, cookies=cookies)
with open('D:/06.jpg', 'wb') as fd:
# fd.write(res.content)
for bs in res.iter_content(1024):
fd.write(bs)
# 还可以使用会话模式,模拟登录后访问
url = 'http://ip:81/'
with requests.Session() as s:
s.post(url + "login", data={'username': '123', 'password': '123'})
res = s.get(url)
print(res.text, s.cookies.values(), "\n", res.request)
这是一个功能强大的网络请求库,要比urllib好用不知道多少倍。不知道java中有没有类似的库。官方文档
第四步:使用pyquery代替正则
看过几个文档分析库效率的测试,正则首当其冲效率最高,然后顺序是lxml
>pyquery
>Beautiful Soup
。看数据pyquery
和lxml
的差距微乎其微。这里我直接选择使用pyquery
,因为其完全仿照JQuery
语法,对于学了一段时间前端的我这可是相当熟悉的,并且它的效率也挺好。
简单使用:
from pyquery import PyQuery as pq
# 导入后这时候需要使用pq构造一个PyQuery对象,这里可以传入文件,html字符串和url,
# 然后返回的这个PyQuery对象就相当于JQuery中的$符号,可以想使用JQuery那样对文档进行各种操作,十分方便
import requests
res = requests.get('http://www.baidu.com')
res.encoding = 'utf-8'
html = res.text
doc = pq(html)
doc = doc.find('title')
print(doc.html())
# 这样就获取到了百度首页的标题
结语
暂时只学到这里,关于动态加载的内容还没有尝试,模仿浏览器的那几个库也还没有学习,继续吧。
然后我就尝试去爬取了下妹子图的图片~~咦。源码: Python版,Java版。java的需要导入jsoup这个jar包才能运行。
网友评论