简单自动化爬虫开发
requests库:get和post
get
import requests
requests.get(url).content.decode()
request.get('url') // get请求,返回一个Response对象。
.content 显示byte型的网页源代码
decode 将byte型的网页源代码解码为字符串型的源代码(中文),里面可以填写解码类型,比如
- decode('utf-8/gb2312/gb18030')
# 获取网页源代码
import requests
html_str = requests.get('https://www.cnblogs.com/lsm-boke/p/8849067.html').content.decode()
print(html_str)
# get和正则匹配使用
# get方式获取
import requests
import re
web_content = requests.get('http://exercise.kingname.info/exercise_requests_get.html').content.decode()
# 标题
title = re.search('title>(.*?)<', web_content, re.S).group(1)
# 提取内容
content_list = re.findall('<p>(.*?)<', web_content, re.S)
content_str = '\n'.join(content_list)
print(content_str)
post
import requests
data = {'key1':'value1','key2':'value2'}
# 普通的表单提交
html_formdata = requests.post(url, data=data).content.decode()
# 提交的内容为json格式
html_json = requests.post(url, json=data).content.decode()
博客园里面的相关博文
import requests
data = {"itemId":8849067,"itemTitle":"如何在Pycharm中添加新的模块"}
html_json = requests.post('https://recomm.cnblogs.com/api/v2/recomm/blogpost/reco',json=data).content.decode()
print(html_json)
多线程爬虫
单线程
import time
import requests
def query(url):
requests.get(url)
start = time.time()
for i in range(100):
query('https://www.baidu.com')
end = time.time()
# 单线程访问百度首页用时31.540141344070435
print(f'单线程访问百度首页用时{end - start}')
多线程
python的多线程其实是伪多线程(全局解释器Global Interpreter Lock)_,本质还是一个县城,但是每个线程每件事情只做几毫秒,几毫秒以后就保存现场,换做其他事情,几毫秒后再做其他事情,一轮之后回到第一件事情上。切换线程需要时间。多线程适合I/O密集型操作。爬虫属于IO密集型程序。
multiprocessing多进程库,其中的dummy模块可以实现多线程。dummy下的Pool类,可以实现线程池。线程池中有一个map方法,可以让线程池里面所有线程都执行一个函数。
from multiprocessing.dummy import Pool
# 计算某些数的平方
for i in range(10):
print(i**i)
# 多线程计算某些数的平方
def calc_power(num):
return num**num
# 初始化一个3个线程的线程池, 线程池负责10个数字的平方计算
pool = Pool(3)
# 列表生成0-9
# origin_num = [x for x in range(10)]
origin_num = range(1, 10)
print(origin_num)
# map(函数名字,列表、元祖、集合或者字典)
# 指定线程池要执行的函数
result = pool.map(calc_power, origin_num)
print(f'计算0-9的平方分别为:{result}')
实例:访问100次百度首页
import time
import requests
from multiprocessing.dummy import Pool
def query(url):
requests.get(url)
start = time.time()
url_list = []
for i in range(100):
url_list.append('https://www.baidu.com')
pool = Pool(15)
pool.map(query, url_list)
end = time.time()
# 5线程访问100次百度首页用时7.350023031234741
# 10线程访问100次百度首页用时4.08358097076416#
# 15线程访问100次百度首页用时2.8800082206726074
# 20线程访问100次百度首页用时4.940855503082275
print(f'15线程访问100次百度首页用时{end - start}')
线程池的大小需要根据实际情况来确定,并没有确切的数据。可以在具体的应用场景下设置不同的大小进行测试对比,找到一个合适的数据。比如此例中,线程池的大小为15时仅为2s多即可全部访问完毕
事件驱动异步模型
闹钟:到规定的时间做相应的动作就好,没有必要每分每秒去检查
算法:广度优先与深度 优先算法
广度优先算法
接下所有任务,层级优先,分支次之
深度优先算法
一个领一个任务,做完一个任务再去领下一个。
分支优先,层级随后
采取广度优先还是深度优先算法
具体情况,具体分析,将两者结合起来