自学爬虫知识整理

request库、bs4库

1.request
根据http协议,常用的是get与post
get:向我们要爬的网页提出“显示”请求;
post:向网页提交数据,比如在搜索框里输入信息,上传文件这种。

import requests
r = requests.get("https://www.baidu.com/")

这样就得到了一个response对象r,包含了想要的网页信息。
因为百度不需要登录就可以访问,所以这是最基本的,但是实际情况中,我们经常要添加headers用于模拟浏览器,添加cookies是存储表单密码的cookie(这句话目前没太大的感觉,不是特别懂)。
一般网页都会带着参数,以前都是手动地改一些,或者用“+”来改网页的字符串,这里学到了一个新的字典用法:

paylod = {'key1': 'value1', 'key2': ['value2', 'value3']}
r = requests.get('https://www.zhihu.com/get', params = payload)

那么r就是这样的:

https://www.zhihu.com/get?key1=value1&key2=value2&key2=value3

得到了r,我们就先想知道r包含的内容

print(r.text)

就可以展示返回的response对象
同时可以先利用r.status_code查看是不是200,ok的链接状态,如果不是的话,可以去百度搜索自己当前返回的状态是什么意思。

post可以使用data或者是json传入数据,一般比如我们要在百度搜索框里输入内容,然后进行查找这样的情况。
第一种json格式的数据,可以直接上传,使用方法和上面提到的一样:

paylod = {'key1': 'value1', 'key2': ['value2', 'value3']}
r = requests.post('https://www.baidu.com/s', json = payload)

百度搜索关键词的接口wd=“要输入的词”
像这种json数据,上传后将自动编码并将Content-Type的值置为application/json
这里补一下http:content-type的知识:
content-type内容类型是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件。
在我理解看来,就是我们用post向服务器提交数据,服务器怎么去看待我们发送来的数据。具体的对照表可以看参考资料3第三个。
第二种上传的数据是data数据,data数据可以分为1.字符串以及2.字典、元组组成的列表;
1.如果传的是字符串,其实就是上面参数json=变成了data=,同时还要设定headers,因为字符串的话,Content-Type就是None。

payload = {'key1': 'value1', 'key2': 'value2'}
headers={"Content-Type": "application/json"}
r = requests.post("https://www.baidu.com/s", headers=headers,data=json.dumps(payload))

我们发现json=payload和data=json.dumps(payload)好像都能完成上传的任务。
我们知道payload是字典格式,那么我们现在想用json格式上传,而且还想用data参数,那么就要用到json库。

import json
<json> = json.dumps(<dict>)
<dict> = json.loads(<json>)

根据这样的方式,我们就可以很容易将dict变成了json类型,但是其实python中是没有json类型的,得到的json其实是字符串类型,这样其实就回应了我们的要求。
但是根据参考资料4,通过这种方式得到的json的字符串类型与str()是不相同的,str存储中对应的是单引号,而json字符串对应的是双引号。
2.如果传的是字典或元组组成的列表

# 字典
payload1 = {'key1': 'value1', 'key2': 'value2'}  
r = requests.post("https://www.baidu.com/s", data=payload1)
# 元组组成的列表
payload2 = [('key1', 'value1'), ('key1', 'value2')]  
r = requests.post("https://www.baidu.com/s", data=payload2)

2.bs4
bs4在我理解起来就是对网页进行解析,在网上看到他只能解析html格式的。
bs4中使用的一个类:BeautifulSoup,这个类可以帮助解析网页中的内容,所谓想要什么提取什么。
使用lxml解析库,该库可以同时解析html和xml文档,在初始化的时候第二个参数设置为lxml。
1.调用prettify( )方法。这个方法可以把要解析的字符串以标准的缩进格式输出。
2.提取节点信息:
(1)获取节点名称:

from bs4 import BeautifulSoup
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>','lxml')
tag = soup.b
print("Tagname:",tag.name)

输出:

('Tagname', u'b')

(2)获取属性:

from bs4 import BeautifulSoup
soup = BeautifulSoup('<p class="title" name="Hello"><b>Hello world</b></p>','lxml')
print(soup.p.attrs)
print(soup.p.attrs['class'])

输出:

{'class': ['title'], 'name': 'Hello'}
['title']

class对应的title使用的是列表进行保存是因为class属性可以有多个值。
(3)获取内容

print(soup.p.string)

输出:

Hello world

如果文档有多个p标签,用我们这种方法返回的是第一个p标签。
那么其实更常用的,就是我们通过定位得到了这个p标签,然后对他进行操作。
寻找我们需要的标签的知识:
分为1.通过父子兄弟节点来定位;2.通过find等方法来查找;3.通过css选择器用select来找。我没怎么学过前端的知识,目前觉得2是最常用的,在这里记录一下1和2部分,如果想看3的部分,可以移步参考资料2。
第一种,通过亲戚节点定位:
(1)选取子节点、子孙节点:
在当前节点的基础上加入:
.contents
.children:可以用for循环来输出
descendants(子孙节点):for循环输出,子节点内还有子节点,也会单独再输出一遍。
(2)父节点:
.parent:直接父亲节点
.parents:祖先节点:for循环输出
(3)兄弟节点:
next_sibling、previous_sibling、next_siblings、previous_siblings
第二种,利用find等方法来查找:
如果html文档非常复杂,那么使用find方法会更容易一些。
find()是返回第一个,find_all()返回所有。

print(soup.find_all(name='a'))
print(soup.find_all(attrs={'id': 'link1'}))

find方法也可以结合亲戚节点来使用。

如果是向百度提交一些搜索词,得到新的网页进行爬取信息,那么就可以利用网页链接的改变来进行,当然也可以利用selenium等技术,模拟人进行点击。
参考资料:
requests:你爬虫的第一步.
python爬虫:史上最详细的BeautifulSoup教程
HTTP content-type
request的pos()方法中的data参数和json参数
request的post请求中json和data区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值