对于具有大量数据的爬虫任务,单进程/线程就会显得捉襟见肘,爬取速度会比较慢,如果需要加快速度,就需要选择多线程/协程 进行处理;如果反爬虫中有对js代码进行加密的时候,一般的爬虫手段都会失效,那么解决的办法有一种就是,直接调用Selenium测试框架控制浏览器进行代码自动发送请求,对返回的真实页面的数据进行解析;在爬虫过程中,如果有验证码图片的时候,对于一般的黑白清晰字码,可以使用tesseract模块进行识别。
多任务进行爬虫
- 多任务爬虫的目标就是更快的将数据爬下来,对比单线程爬取和多任务(多线程,协程爬取的时间)
示例对比:爬取豆瓣电影top250
单线程爬虫
代码:
# -*- coding:utf-8 -*-
import requests
import json, time
from lxml import etree
class Spider_Douban(object):
def __init__(self):
self.base_url = 'https://movie.douban.com/top250?filter=&start='
self.headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'}
self.data_list = []
# 发送请求
def send_request(self, url):
data = requests.get(url, headers=self.headers).content
return data
# 数据解析
def parse_data(self, data):
html = etree.HTML(data)
data_list = html.xpath('//*[@id="content"]/div/div[1]/ol/li/div/div[2]/div[1]/a/span[1]/text()')
for data in data_list:
self.data_list.append(data)
# 保存数据到本地
def save_data(self):
data_json = json.dumps(self.data_list)
with open('03_spider_douban.json', 'w') as f:
f.write(data_json)
# 主逻辑
def main(self):
import time
start_time = time.time()
for page in range(0, 225 + 1, 25):
url = self.base_url + str(page)
# 发送数据
data = self.send_request(url)
# 数据解析
self.parse_data(data)
print '正在爬第--%d--页' % ((page / 25) + 1)
# 保存数据
self.save_data()
end_time = time.time()
time = end_time - start_time
print '单线程所需时间为:%s' % time
# 单线程所需时间为:2.55781912804
if __name__ == '__main__':
spider_douban = Spider_Douban()
spider_douban.main()
多线程
步骤
- 导入模块:import threading
- 将任务加入到异步线程中:threading.Thread(target=self.change_value)
- 开始线程:t1.start()
注意点:将子线程加入到主线程中:t1.join()
代码
# -*- coding:utf-8 -*-
import threading