Python进程+协程——从零开始搭建异步爬虫(1)
很多人入门 Python 是从爬虫开始的,笔者也不例外。爬取大量网页需要用到多进程、多线程、协程等等特性,而这类代码的编写往往比较繁琐,如果经常需要爬取不同的网页,我们往往会用到 scrapy 等爬虫框架以减少工作量。笔者最近正好需要大量爬取一些内容,本着学习的目的,我们不使用爬虫框架,从零开始搭建一个简单的异步爬虫。
目标
利用协程异步请求网页。
利用多进程加快爬取速度。
提供需要请求的链接,设定好处理流程后,程序自动按顺序处理。
简易流程图
需要用到的库
pipenv 创建虚拟环境,以免影响原有环境
aiohttp 是基于 asyncio 实现的HTTP框架
环境搭建
安装 pipenv(参考官方教程)
打开终端,在合适的位置创建文件夹,并进入文件夹
12mkdir AiospiderWorkshopcd AiospiderWorkshop
创建虚拟环境
1pipenv install --python 3.8
更换 pipenv 源为阿里云源
123456# 打开 Pipfile 文件,修改 source 部分如下[[source]]url = &qu ...
PAT(Basic Level) 1017 A除以B (20)
本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数。你需要输出商数Q和余数R,使得A = B * Q + R成立。
项目
要求
时间限制
100 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数。你需要输出商数Q和余数R,使得A = B * Q + R成立。
输入格式输入在1行中依次给出A和B,中间以1空格分隔。
输出格式在1行中依次输出Q和R,中间以1空格分隔。
输入样例123456789050987654321 7
输出样例17636684150141093474 3
代码实现C语言1234567891011121314151617181920212223242526272829303132#include <stdio.h>#include <string.h>int main() { char A[1000]; int B, quotient, re ...
PAT(Basic Level) 1016 部分A+B (15)
正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA。例如:给定A = 3862767,DA = 6,则A的“6部分”PA是66,因为A中有2个6。
项目
要求
时间限制
100 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA。例如:给定A = 3862767,DA = 6,则A的“6部分”PA是66,因为A中有2个6。
现给定A、DA、B、DB,请编写程序计算PA + PB。
输入格式输入在一行中依次给出A、DA、B、DB,中间以空格分隔,其中0 < A, B < 1010。
输出格式在一行中输出PA + PB的值。
输入样例13862767 6 13530293 3
输出样例1399
输入样例23862767 1 13530293 8
输出样例20
代码实现C语言1234567891011121314151617181920212223#include <stdio.h&g ...
PAT(Basic Level) 1014 福尔摩斯的约会 (20)
大侦探福尔摩斯接到一张奇怪的字条:“我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm”。
项目
要求
时间限制
100 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
大侦探福尔摩斯接到一张奇怪的字条:“我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm”。大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的时间“星期四 14:04”,因为前面两字符串中第1对相同的大写英文字母(大小写有区分)是第4个字母’D’,代表星期四;第2对相同的字符是’E’,那是第5个英文字母,代表一天里的第14个钟头(于是一天的0点到23点由数字0到9、以及大写字母A到N表示);后面两字符串第1对相同的英文字母’s’出现在第4个位置(从0开始计数)上,代表第4分钟。现给定两对字符串,请帮助福尔摩斯解码得到约会的时间。
输入格式输入在4行中分 ...
06-图1 列出连通集(25 分)
给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。
输入格式输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。
输出格式按照”{ v1 v2 … vk}”的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。
输入样例12345678 60 70 12 04 12 43 5
输出样例123456{ 0 1 4 2 7 }{ 3 5 }{ 6 }{ 0 1 2 7 4 }{ 3 5 }{ 6 }
代码实现C语言1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 ...
05-树7 堆中的路径(25 分)
将一系列给定数字插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。
输入格式每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。
输出格式对输入中给出的每个下标i,在一行中输出从H[i]到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。
输入样例1235 346 23 26 24 105 4 3
输出样例12324 23 1046 23 1026 10
代码实现C语言1234567891011121314151617181920212223242526272829303132333435363738#include<stdio.h>#define MAXN 1001#define MINH -10001int H[MAXN], size;void Create() { size = 0; H[0] = MINH;}void Inse ...
03-树3 Tree Traversals Again(25 分)
An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.
Figure 1
Input Specif ...
03-树2 List Leaves(25 分)
Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.
Input SpecificationEach input file contains one test case. For each case, the first line gives a positive integer N (≤10) which is the total number of nodes in the tree – and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a “-“ will be put at the position. Any ...
03-树1 树的同构(25 分)
给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。现给定两棵树,请你判断它们是否是同构的。
给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。
图1
图2
现给定两棵树,请你判断它们是否是同构的。
输入格式输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。
输出格式如果两棵树是同构的,输出“Yes”,否则输出“No”。
输入样例1(对应图1)1234567891011121314151617188A 1 2B 3 4C 5 -D - -E 6 -G 7 -F - -H - ...
02-线性结构4 Pop Sequence(25 分)
Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, …, N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.
Input SpecificationEach input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M (the maximum capacity of the stack), N (the ...