相对于python自带的urllib模块,requests模块提供了相对更高层的api来进行网页访问的工做。html
对于requests模块,使用很简单,通常咱们会用到两个函数:python
以上两个函数分别对应http协议中的"GET"方法与"POST"方法,除了这二者,还有如"PUT"、"DELETE"等方法,在requests模块中有一个统一的函数来发起不一样“方法”的http请求报文:程序员
def get(url, params=None, **kwargs): kwargs.setdefault('allow_redirects', True) #这里可见request.get的实质 return request('get', url, params=params, **kwargs)
这里来详细介绍一下headers,proxies和stream关键字参数的用途:正则表达式
这两个对象详细对爬虫有过了解的朋友们都很熟悉了,它们是在爬虫逻辑中很关键的两个对象,简单来讲:发出Request,返回Response。json
咱们在使用requests时通常不会直接建立Request对象,因此这里咱们大体了解一下便可:api
requests.Request(method=None, url=None, headers=None, data=None, params=None) 咱们列出Request类构造时所需的一些经常使用参数,而且前文咱们提到requests.get等函数的实质是requests.request函数,那么其实研究该函数的源码:浏览器
def request(method, url, **kwargs): with sessions.Session() as session: #能够看到在request函数内调用了session.request方法 return session.request(method=method, url=url, **kwargs) #这个是session.request方法的定义 def request(self, method, url, params=None, data=None, headers=None, cookies=None, files=None, auth=None, timeout=None, allow_redirects=True, proxies=None, hooks=None, stream=None, verify=None, cert=None, json=None): #能够看到这里其实使用传入参数 #建立了一个requests.Request实例 req = Request( method=method.upper(), url=url, headers=headers, files=files, data=data or {}, json=json, params=params or {}, auth=auth, cookies=cookies, hooks=hooks, ) #进一步处理,获得对应的PreparedRequest对象 prep = self.prepare_request(req) proxies = proxies or {} settings = self.merge_environment_settings( prep.url, proxies, stream, verify, cert ) # Send the request. send_kwargs = { 'timeout': timeout, 'allow_redirects': allow_redirects, } send_kwargs.update(settings) #这里是真正的send Request,并返回一个Response对象 resp = self.send(prep, **send_kwargs) return resp
由以上代码可知,其实requests.request方法的实质就是建立一个Request实例,在对其进行必定预处理后将其send,而后获得Response。cookie
咱们以前的requests.get、requests.post或是requests.request函数的返回对象就是一个requests.Response实例。对于Response类,咱们主要介绍几个经常使用属性与方法:session
BeautifulSoup是一个能够从HTML或XML文件中提取数据的Python库,一般咱们使用requests获得html文件(Response.text),而后咱们再使用BeautifulSoup来处理。从而提取到咱们须要的信息。函数
from bs4 import BeautifulSoup #其中html是返回的网页文本,也就是response.text #而lxml是BeautifulSoup使用的文档解析器,须要咱们 #已经预先pip install好lxml这个模块,或者咱们也可 #使用python自带的html.parser,不过它的速度较慢些 #而soup就是一个BeautifulSoup对象,它承载了一个 #由html文档内部各个元素所造成的树形结构。 soup=BeautifulSoup(html,"lxml") #如下就是几个最简单基本的使用 #直接以属性引用的方式获得html文档中的第一个a标签 print(soup.a) #进一步获得html文档中第一个a标签的中的字符串部分(若是存在的话) print(soup.a.string) #拿到html文档中第一个a标签的href属性的值 print(soup.a["href"])
以上大体介绍了BeautifulSoup的简单实用,接下来咱们进行更详细地分析:
BeautifulSoup将HTML文档转换成一个复杂的树形结构,该树形结构中的每一个节点都是Python对象,全部对象可分为4种: Tag、NavigableString、BeautifulSoup、Comment。
接下来咱们要来对tag对象以及BeautifulSoup对象在使用method上进行更进一步的介绍:
而所谓的method使用,咱们着眼的就是在获得的BeautifulSoup对象的树形结构中对所须要的信息进行搜索的工做。
这样的搜索工做根据对节点自己信息和节点之间在树形结构中的关系的应用不一样而分为两种。
第一种,由节点自己信息对节点进行搜索:
所谓tag.a其实就是tag.find("a"),该方法的具体函数头以下 find(name,attrs,recursive,string,**kwargs) name就是标签名,它的值是一个“过滤器”。 attrs就是该name对应标签的属性,一样值也是一个“过滤器”。 recursive是一个bool值,默认为True。它的意思是搜索当前tag的全部子孙节点,若是为False,则只搜索当前tag的直接子节点 string就是该name对应的string值,也是一个“过滤器”。 **kwargs通常使用不用理会。 固然上面的tag.a或是tag.find("a")都只能获得tag下的第一个a标签, 这太局限了,若是咱们想要的是后面的第三个a标签呢?因而就有了 tag.find_all("a")方法,返回一个列表,来获得全部的a标签,简写为tag("a")。 find_all(name,attrs,recursive,string,**kwargs) 参数的意义和find函数同样 下面咱们来说解一下这个所谓的“过滤器”究竟是什么东西 具体的代码实现有点繁琐,总之咱们能够把它理解为一种 对象,咱们容许这个对象有多种值。 (1)字符串值 最简单的就是传入字符串值,如以前的tag.a (2)正则表达式值 即re.compile(r"\d+")这样的形式 (3)列表值 如name=["a","div"],则find只会返回其中的后者, find_all会返回一个列表,包含tag下的全部a和div标签。 (4)True 意思不作过滤,对于find是返回tag下符合要求的标签的第一个,对于find_all是返回全部。好比name=True,那么就不对name 过滤,对其余attrs或string继续筛选过滤。
第二种,根据节点所在树形结构中的关系对其它节点进行搜索:
直接子节点: tag.childern和tag.contents是tag对象的两个属性,注意不是对应标签的属性!!!它们返回当前tag节点在树形结构中的直接子节点。 tag.childern返回一个生成器 tag.contents返回一个列表 子孙节点: tag.descendants返回一个生成器,对它进行遍历能够获得当前tag节点的全部子孙节点的循环遍历结果。 直接父节点: tag.parent获取当前tag的直接父节点 因此父节点: tag.parents返回一个生成器,能够获取当前tag的全部父辈节点 next的兄弟节点: tag.next_sibling和tag.next_siblings,返回值类型不用赘述。 previous的兄弟节点: tag.previous_sibling和tag.previous_siblings,一样返回类型不用赘述。
以上大概就是BeautifulSoup在搜索信息时所需的知识,其它如两种方式结合的tag.find_parent(name,attrs,recursive,string,**kwargs)等方法,以后能够慢慢了解。