500lines之crawler学习(二)

一、先看看两个函数的用法:

normalized = urllib.parse.urljoin(response.url, url)
defragmented, frag = urllib.parse.urldefrag(normalized)

参考文章:

https://pythoncaff.com/docs/pymotw/urllibparse-split-urls-into-components/149

urllib.parse.urljoin(baseurlallow_fragments=True

可以用它从相对地址的片段中创建出绝对 URLs 地址 。

print(urljoin('http://www.example.com/path/file.html','anotherfile.html'))
print(urljoin('http://www.example.com/path/file.html','../anotherfile.html'))
print(urljoin('http://www.example.com/path/','/subpath/file.html'))
print(urljoin('http://www.example.com/path/','subpath/file.html'))

输出结果: 

http://www.example.com/path/anotherfile.html

http://www.example.com/anotherfile.html

http://www.example.com/subpath/file.html

http://www.example.com/path/subpath/file.html

urllib.parse.urldefrag(url)

如果url包含一个片段标识符,则返回一个没有片段标识符的修改过的url(URL with no fragment),并且这个片段标识符作为单独的字符串。

如果url中没有片段标识符,则返回未修改的url和一个空字符串(Fragment identifier)。

from urllib.parse import urldefrag

original = 'http://netloc/path;param?query=arg#frag'
print('original:', original)
d = urldefrag(original)
print('url     :', d.url)
print('fragment:', d.fragment)

输出结果:

original: http://netloc/path;param?query=arg#frag

url : http://netloc/path;param?query=arg

fragment: frag

二、关于aiohttp

参考文章:

https://segmentfault.com/a/1190000012141784

基本用法如下:

import aiohttp,asyncio

async def fetch(session,url):
    async with session.get(url,allow_redirects=False) as resp:
        print(resp.status)
        return await resp.text() #text()方法是协程方法,所以需要用await关键字

async def main(loop):
    url = 'https://xkcd.com'
    async with aiohttp.ClientSession() as session:
        html = await fetch(session,url)
#        print(html)

loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
loop.close()

从Python 3.5开始引入了asyncawait,都是针对coroutine的,要使用新语法,只要做两步替换:

  1. @asyncio.coroutine替换为async
  2. yield from替换为await

全局函数 request()

如果request,代码如下:

async def main():
    url = 'https://xkcd.com'
    async with aiohttp.request("GET",url) as resp:
        html = await resp.text(encoding="utf-8")
        print(html)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

request() 只是 ClientSession 的一个简单封装,其步骤大致为:

  • 创建 TCPConnector
  • 创建 ClientSession
  • 调用 ClientSession._request()

多个url时:

async def fetch_url(url):
    async with aiohttp.request("GET",url) as resp:
        html = await resp.text(encoding="utf-8")
        print(html)
        
tasks = [fetch_url('https://xkcd.com'),fetch_url('http://www.baidu.com')]

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks))
loop.close()

gather 起聚合的作用,把多个 futures 包装成单个 future,因为 loop.run_until_complete 只接受单个 future。

一个 request 用一个 session,太浪费;通常是一个 application 用一个 session。

推荐用法:

async def fetch(session,url):
    async with session.get(url,allow_redirects=False) as resp:
        print(resp.status)
        return await resp.text() #text()方法是协程方法,所以需要用await关键字

async def main():
    url1 = 'https://xkcd.com'
    url2 = 'http://www.baidu.com'
    async with aiohttp.ClientSession() as session:
        html1 = await fetch(session,url1)
        html2 = await fetch(session,url2)
        print(html1)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值