爬虫

一、异步IO

线程:线程是计算机中工作的最小单元

​ IO请求(IO密集型)时多线程更好,计算密集型进程并发最好,IO请求不涉及CPU

自定义线程池

进程:进程默认有主线程,可以有多线程共存,并且共享内部资源

自定义进程

协程:使用进程中一个线程去完成多个任务,微线程(伪线程)

GIL:python特有,用于在进程中对线程枷锁,保证同一时刻只能有一个线程被CPU调度

# Author:wylkjj
# Date:2020/2/24
# -*- coding:utf-8 -*-
import requests
# 创建多线程
from concurrent.futures import ThreadPoolExecutor
# 创建多进程
from concurrent.futures import ProcessPoolExecutor def async_url(url):
try:
response = requests.get(url)
except Exception as e:
print('异常结果', response.url, response.content)
print('获取结果', response.url, response.content) url_list = [
'http://www.baidu.com',
'http://www.chouti.com',
'http://www.bing.com',
'http://www.google.com',
]
# 线程池pool:创建五个线程,IO请求线程更适合
# GIL线程锁,只针对cpu的调用权限,针对IO请求不会锁住
pool = ThreadPoolExecutor(5)
# 进程池pools:创建五个线程,进程浪费资源
pools = ProcessPoolExecutor(5) for url in url_list:
print('开始请求:', url)
pool.submit(async_url, url) pool.shutdown(wait=True) # 回调函数:.add_done_callback(回调的函数)

异步IO模块:

import asyncio缺点:只提供TCP,提供sleep,不提供http

​ 事件循环:get_event_loop()

​ @asyncio.coroutine和yield from要同时配套使用,固定写法

​ 异步IO:

  • asynico + aiohttp:asynico + request
  • gevent + request:gevent + request两个方法组合在一起后出现了一个grequests
  • twisted
  • tornado:异步非阻塞IO
# Author:wylkjj
# Date:2020/2/24
# -*- coding:utf-8 -*-
# 异步IO模块
import asyncio @asyncio.coroutine
def func1():
print('before...func1......')
yield from asyncio.sleep(5)
print('end...func1......') tasks = [func1(), func1()]
loop = asyncio.get_event_loop() # 事件循环
loop.run_until_complete(asyncio.gather(*tasks)) # 把任务作为列表传进来
loop.close() # Author:wylkjj
# Date:2020/2/25
# -*- coding:utf-8 -*-
import asyncio @asyncio.coroutine
def fetch_async(host, url='/'):
print(host, url)
reader, writer = yield from asyncio.open_connection(host, 80) request_header_content = """GET %s HTTP/1.0\r\nHost: %s\r\n\r\n""" % (url, host,)
request_header_content = bytes(request_header_content, encoding='utf-8') writer.write(request_header_content)
yield from writer.drain()
text = yield from reader.read()
print(host, url, str(text, encoding='utf-8'))
writer.close() tasks = [
fetch_async('www.cnblogs.com', '/eric/'),
fetch_async('dig.chouti.com', '/pic/show?nid=4073644713430508&lid=10273091')
] loop = asyncio.get_event_loop()
results = loop.run_until_complete(asyncio.gather(*tasks))
loop.close() # Author:wylkjj
# Date:2020/2/25
# -*- coding:utf-8 -*-
# 使用aiohttp和asyncio实现http请求 (aiohttp亲)
import aiohttp
import asyncio @asyncio.coroutine
def fetch_async(url):
print(url)
response = yield from aiohttp.request('GET', url)
# data = yield from response.read()
# print(url, data)
print(url, response)
response.close() # Author:wylkjj
# Date:2020/2/25
# -*- coding:utf-8 -*-
# asyncio和requests配合使用也可以支持HTTP (requests后)
import asyncio
import requests @asyncio.coroutine
def fetch_async(func, *args):
print(args)
# 事件循环
loop = asyncio.get_event_loop()
future = loop.run_in_executor(None, func, *args)
response = yield from future
print(response.url, response.content) tasks = [
fetch_async(requests.get, 'http://www.cnblogs.com/eric/'),
fetch_async(requests.get, 'http://dig.chouti.com/pic/show?nid=4073644713430508&lid=10273091')
] loop = asyncio.get_event_loop()
results = loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
# Author:wylkjj
# Date:2020/2/25
# -*- coding:utf-8 -*-
import gevent
from gevent import monkey
monkey.patch_all() import requests def fetch_async(method, url, req_kwargs):
print(method, url, req_kwargs)
response = requests.request(method=method, url=url, **req_kwargs)
print(response.url, response.content) # ##### 发送请求 #####
gevent.joinall([
gevent.spawn(fetch_async, method='get', url='https://www.python.org/', req_kwargs={}),
gevent.spawn(fetch_async, method='get', url='https://www.yahoo.com/', req_kwargs={}),
gevent.spawn(fetch_async, method='get', url='https://github.com/', req_kwargs={}),
])
# pip3 install twisted
# pip3 install wheel
# b. 下载twisted http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
# c. 进入下载目录,执行 pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl from twisted.web.client import getPage
from twisted.internet import reactor REV_COUNTER = 0
REQ_COUNTER = 0 def callback(contents):
print(contents,) global REV_COUNTER
REV_COUNTER += 1
if REV_COUNTER == REQ_COUNTER:
reactor.stop() url_list = ['http://www.bing.com', 'http://www.baidu.com', ]
REQ_COUNTER = len(url_list)
for url in url_list:
print(url)
deferred = getPage(bytes(url, encoding='utf8'))
deferred.addCallback(callback)
reactor.run()

import socket:它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。

tronado框架原理

自定义异步IO:

基于socket,setblocking(False)

IO多路复用(也是同步IO)

while True:

r,w,e = select.select([ ],[ ],[ ],1)

关于IO的详情博客:事件驱动IO模型:https://www.cnblogs.com/wylshkjj/p/10896994.html

二、scrapy框架

scrapy框架的安装

​ Linux

pip3 install scrapy

​ Windows

​ 1.

​ pip3 install wheel

​ 安装Twisted:版本信息知识一个格式,非正确版本

​ a. http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted, 下载:Twisted-19.1.0-cp37-cp37m-win_amd64.whl

​ b. 进入文件所在目录

​ c. pip3 install Twisted-19.1.0-cp37-cp37m-win_amd64.whl

​ 2.

pip3 install scrapy:,此版本与urllib3模块产生冲突,如有此模块需要先卸载此模块

​ 3.

​ windows上scrapy依赖 https://sourceforge.net/projects/pywin32/files/

项目的创建和执行

  1. scrapy使用方法
  2. 创建新项目命令:scrapy startproject scy (在想要创建的目录中执行此命令,scy是项目名)
  3. 创建一个爬虫:scrapy genspider example example.com (创建爬虫要先cd 到项目的目录中,example是爬虫文件名字,example.com 是所爬网页地址)
  4. 项目的执行命令:scrapy crawl chouti (抽屉是所要执行的爬虫文件)
  5. 过滤日志命令:scrapy crawl chouti --nolog (过滤chouti 爬的数据日志)
  6. 查看爬虫模板命令:scrapy genspider --list(显示四个模板:basic,crawl,csvfeed,xmlfeed)
  7. 防止蜘蛛(genspider )的权限,robkts.txt属性,在项目setting配置文件中修改ROBOTSTXT_OBEY属性使其值为ROBOTSTXT_OBEY=False
  8. project_name/
    • scrapy.cfg 项目的主配置文件
    • project_name/
      • __init__.py
      • items.py 设置数据存储模板,用于结构化数据,如:Django的Model
      • pipelines.py 数据处理行为,如:一般结构化的数据持久化
      • settings.py 真正配置文件,如:递归的层数,并发数,延迟下载等
      • spiders/ 爬虫目录,如:创建文件,编写爬虫规则
        • __init__.py
        • 爬虫1.py
        • 爬虫2.py
  9. 注意:创建爬虫还是要在命令行创建,运行项目,运行爬虫文件都要在命令行执行
# 部分项目代码展示,爬取优美图库图片
# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request
from bs4 import BeautifulSoup class UmeiSpider(scrapy.Spider):
name = 'umei'
allowed_domains = ['umei.cc']
start_urls = ['https://www.umei.cc/meinvtupian/meinvxiezhen/1.htm']
visited_set = set() def parse(self, response):
self.visited_set.add(response.url) # 已经爬取的网页
# 1.将当前页所有的meizi图片爬下来
# 获取a标签并且属性为 class = TypeBigPics
main_page = BeautifulSoup(response.text, "html.parser")
item_list = main_page.find_all("a", attrs={'class': 'TypeBigPics'})
for item in item_list:
item = item.find_all("img",)
print(item) # 2.获取:https://www.umei.cc/meinvtupian/meinvxiezhen/(\d+).htm
page_list = main_page.find_all("div", attrs={'class': 'NewPages'})
a_urls = 'https://www.umei.cc/meinvtupian/meinvxiezhen/'
a_list = page_list[0].find_all("a")
a_href = set()
for a in a_list:
a = a.get('href')
if a:
a_href.add(a_urls+a)
else:
pass
for i in a_href:
if i in self.visited_set:
pass
else:
obj = Request(url=i, method='GET', callback=self.parse)
yield obj
print("obj:", obj)

爬虫基础知识及scrapy框架使用和基本原理的更多相关文章

  1. Python爬虫进阶三之Scrapy框架安装配置

    初级的爬虫我们利用urllib和urllib2库以及正则表达式就可以完成了,不过还有更加强大的工具,爬虫框架Scrapy,这安装过程也是煞费苦心哪,在此整理如下. Windows 平台: 我的系统是 ...

  2. 爬虫(九)scrapy框架简介和基础应用

    概要 scrapy框架介绍 环境安装 基础使用 一.什么是Scrapy? Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍.所谓的框架就是一个已经被集成了各种功能 ...

  3. python网络爬虫(2)——scrapy框架的基础使用

    这里写一下爬虫大概的步骤,主要是自己巩固一下知识,顺便复习一下. 一,网络爬虫的步骤 1,创建一个工程 scrapy startproject 工程名称 创建好工程后,目录结构大概如下: 其中: sc ...

  4. python 爬虫基础知识一

    网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本. 网络爬虫必备知识点 1. Python基础知识2. P ...

  5. 分布式爬虫搭建系列 之三---scrapy框架初用

    第一,scrapy框架的安装 通过命令提示符进行安装(如果没有安装的话) pip install Scrapy 如果需要卸载的话使用命令为: pip uninstall Scrapy 第二,scrap ...

  6. 爬虫(十五):Scrapy框架(二) Selector、Spider、Downloader Middleware

    1. Scrapy框架 1.1 Selector的用法 我们之前介绍了利用Beautiful Soup.正则表达式来提取网页数据,这确实非常方便.而Scrapy还提供了自己的数据提取方法,即Selec ...

  7. Python3爬虫(十七) Scrapy框架(一)

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 1.框架架构图: 2.各文件功能scrapy.cfg 项目的配置文件items.py 定义了Item数据结构,所有 ...

  8. 爬虫 (5)- Scrapy 框架简介与入门

    Scrapy 框架 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页 ...

  9. Java并发(基础知识)—— Executor框架及线程池

    在Java并发(基础知识)—— 创建.运行以及停止一个线程中讲解了两种创建线程的方式:直接继承Thread类以及实现Runnable接口并赋给Thread,这两种创建线程的方式在线程比较少的时候是没有 ...

  10. 爬虫(十四):Scrapy框架(一) 初识Scrapy、第一个案例

    1. Scrapy框架 Scrapy功能非常强大,爬取效率高,相关扩展组件多,可配置和可扩展程度非常高,它几乎可以应对所有反爬网站,是目前Python中使用最广泛的爬虫框架. 1.1 Scrapy介绍 ...

随机推荐

  1. JDBC批处理Select语句

    本文由 ImportNew - 刘志军 翻译自 Javaranch.如需转载本文,请先参见文章末尾处的转载要求. 注:为了更好理解本文,请结合原文阅读 在上一篇文章中提到了PreparedStatem ...

  2. 成为Java GC专家(4) — Apache的MaxClients参数详解及其在Tomcat执行FullGC时的影响

    这是"成为Java GC专家系列文章"的第四篇. 在第一篇文章 成为JavaGC专家Part I - 深入浅出Java垃圾回收机制 中我们学习了不同GC算法的执行过程,GC如何工作 ...

  3. canvas(七)绘制网格和坐标轴

    1.绘制网格 传入dom和分割线间隔进行渲染,网格线分为水平方向和垂直方向 <script> //绘制网格 function drwaGrid(dom = document.querySe ...

  4. C++之OpenCV入门到提高006:图像混合

    一.介绍 今天是这个系列<C++之 Opencv 入门到提高>的第六篇文章.这篇文章也不难,介绍如何图像的混合操作.图像本质上也是数据,既然是数据,我们就可以针对两张或者多张图片进行加.减 ...

  5. 记ios的input框获取焦点之后界面放大问题

    在移动端开发项目中,发现页面在使用 iPhone 访问的时候,点击 input 和 textarea 等文本输入框聚焦 focus() 时,页面会整体放大,而且失去焦点之后页面不能返回原来的样子.检查 ...

  6. 鸿蒙NEXT开发案例:经纬度距离计算

    [引言] 在鸿蒙NEXT平台上,我们可以轻松地开发出一个经纬度距离计算器,帮助用户快速计算两点之间的距离.本文将详细介绍如何在鸿蒙NEXT中实现这一功能,通过简单的用户界面和高效的计算逻辑,为用户提供 ...

  7. 数据万象推出智能检索MetaInsight,现已开启限时公测

    海量文件的分析统计一直是对象存储COS的热点需求,伴随AIGC飞速迭代发展,在众多不同模态素材的海洋中,用户也急需更高效地管理和利用多媒体内容,打破传统搜索的桎梏. 数据万象推出的智能检索 MetaI ...

  8. 鸿蒙应用开发从入门到入行 - 篇4:层叠布局、自定义组件、ForEach

    第四篇 - 层叠布局.自定义组件.ForEach循环生成组件 导读:在本篇文章里,您将掌握层叠布局.自定义组件的用法,特别是自定义组件将来的开发中必然会用,其中应该特别关注自定义组件的一些规范与装饰器 ...

  9. IOS热重载工具InjectionIII

    IOS热重载工具InjectionIII 支持 OC.Swift 以及 Swift 和 OC 混编项目的 UI 热重载工具,采取在模拟器(真机不支持)注入方式实现 UI 热重载,修改完 UI 直接 c ...

  10. 连续6年夺冠 6项细分领域第一,中电金信持续领跑中国银行业IT解决方案市场

    ​ 7月9日,工信部赛迪顾问发布<2023年度中国银行业IT解决方案市场分析报告>(简称<报告>).中电金信以7.38%的市场份额再度蝉联2023中国银行业IT解决方案市场份额 ...