- 在线时间
- 661 小时
- 最后登录
- 2023-8-1
- 注册时间
- 2017-5-2
- 听众数
- 32
- 收听数
- 1
- 能力
- 10 分
- 体力
- 55539 点
- 威望
- 51 点
- 阅读权限
- 255
- 积分
- 17613
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 447
- 主题
- 326
- 精华
- 1
- 分享
- 0
- 好友
- 79
TA的每日心情 | 慵懒 2020-7-12 09:52 |
|---|
签到天数: 116 天 [LV.6]常住居民II 管理员
 群组: 2018教师培训(呼和浩 群组: 2017-05-04 量化投资实 群组: 2017“草原杯”夏令营 群组: 2018美赛冲刺培训 群组: 2017 田老师国赛冲刺课 |
仅需一行代码写爬虫–simple_crawl
$ a) [. x- e' p" ]5 u# B9 Usimple_crawl
: O7 q( t( n! |1 D7 r) E j仅需一行代码即可达到爬虫效果
5 R; M" `! x( J# I2 b( e$ Q项目地址(欢迎star):https://github.com/Amiee-well/crawl
0 d; k" q# U) F) {5 C; L: h使用方法$ U1 r1 U3 u* f- |
pip install simple_crawl r& i, ]" m5 p0 M) a
$ c ]8 p f% P
### 以下源代码为简单介绍,详细功能介绍再源代码之下
% h: i Q! E4 `+ l, b0 \1 Z' xfrom simple_crawl import request
. U7 }5 h' ?7 m3 D1 x: G4 P( vrequest.parse(0 g6 \" W6 v4 k* u( a- _5 }0 G
# status 参数为运行状态,支持单线程多线程多进程协程以及联合
) `, b* R4 k1 e) s$ r6 |/ k/ ^ status="aiohttp", ~# \0 w7 A) s$ R0 w
# url 参数为爬虫网址,单线程状态为字符串格式,特殊状态为列表格式
4 F8 h6 R* O2 g2 r1 Q; W* ` url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],
8 Y& ]. z$ c: H # login 参数为获取登陆信息,如淘宝等网址需要登陆信息
) P0 I* n( X# V! o% f: Z2 C" d #login="taobao",
5 l1 l) w4 \' ]6 T4 Y # type_url 参数为返回源代码格式,支持text和json,默认返回text
6 F ]& P6 K2 [! h1 z0 M' V5 j type_url = "text",
* z v0 j* o$ ^( q+ q5 U+ ~: A # Parsing 参数为解析方法,支持re、xpath和beautifulsoup% U2 t8 o4 X+ [5 `, y3 ?
Parsing = 'xpath',, v* R: |/ R$ V* x' |- U
# label 参数为爬虫解析过程,字典格式,详情见下方6 |. o+ q2 \4 z1 F1 E
label = {
% Q! q& Q) s$ @ 'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],( j: ^4 C9 L! G& r* _
'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],
' G: f) U8 e5 s+ Y! Q 'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]' M8 r, R! q0 R. T" x
},; B2 H$ P3 X# H, _8 J
# write 参数为爬虫结果保存,支持txt、csv、pkl、json,注:特殊状态爬虫信息容易混乱4 k5 f, M+ a; h/ P' h
write='result.txt',
: g0 D4 L$ a w1 w+ d2 P0 b) o6 k' K2 u # next_url 参数为下一页爬虫地址,@必须为href,仅支持单线程爬虫0 ^. }3 K Q5 y8 D
next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',& t2 {0 C2 M5 a5 k6 t
# page 参数为断续笔记,第一个参数是否启用笔记,第二个参数选填默认page.txt,仅支持单线程爬虫
: q" n) z- Y2 _ page=[True,"now_url.txt"],
0 c. n) Q3 { J: \& t # clean 参数为是否进行数据清洗,防止大量爬虫收集无用信息
4 `$ B2 {- \+ G8 X #clean=True,
. F3 Q8 f( [+ k # texting 参数为是否选择连续爬虫,避免爬虫过程中出现非代码问题报错结束爬虫程序; n* h2 W9 J2 t& \
texting=True,; s1 q8 S7 R& v: Z5 J t8 |$ i& ^
# Thread_num 为多线程数,默认为1单线程,支持多线程状态和异步状态
3 Q* X y4 B' K2 w3 i$ O! ^7 A Thread_num=3,
$ }2 O1 C9 U6 E0 n$ V # cpu_count 为多进程数,默认为1单进程,支持多进程状态和联合状态/ v* D9 K! {. O# i& S7 Z
cpu_count=1,& R. T8 N" f6 T" f& c
# sem 为异步控制数,默认为5同时启动,支持异步状态和联合状态& J+ S/ M/ s8 h( L% V7 ^8 \
sem=5,
' x- M+ R) x7 C6 ?" r # write_SQL 为是否写入数据库,默认否$ c) x; z6 Z0 ?: y% [% t4 ]' V
# host 参数默认localhost- ?" x4 f. L" J8 x: W; A$ N; t
# post 参数默认3306
$ U( |, T8 w1 V- s- k% { # user 参数默认root
O$ Q) N6 w4 c; t8 Z: F) u # password 参数必填,必须正确
! O0 R" N# n" n: @ # db 参数为即将存入的数据库名,若不存在自动创建
! ~# y0 w5 E9 T # table 参数为即将存入的数据表名,若不存在自动创建3 k/ z0 ?& w5 q. W
write_SQL={
) ?* \: L8 V8 d9 F 'host':'localhost',8 d9 c' Q8 o4 Z& a/ u
'post':'3306',
! M3 `9 T$ o$ X0 t; n M 'user':'root',. ]6 h" J$ H* S/ k) U; k1 D, ^! L! D
'password':'123456',0 z5 e- s% \9 E1 ~8 @
'db':'example',8 ]4 K0 X1 r% l4 r, i7 m5 O
'table':'example'
* u1 {7 W5 O$ _ }4 ?/ r' i X8 Y* @: T
).run()
$ o1 i H8 O. c/ q) c
9 \- c8 n' @1 m' v! O) e介绍一下crawl参数设置:
& { q' e, x% u( ~7 ^
2 M. Y, W9 v5 z _, o8 m* Q8 W2 \'''' I; G+ N% I) [9 T. k6 G+ ?
单行代码爬虫程序执行
' A, |; h) a4 T1 @:param status:启用爬虫类型,支持普通爬虫、多进程爬虫、多线程爬虫、异步爬虫、异步多进程爬虫,参数请参考文档
/ n& M: Y; @, H$ k. ~+ b:param url:即将请求的url地址,仅支持get请求8 _8 V N& s* J1 [
:param type_url:请求url后返回格式,支持text和json格式返回
: l/ [$ g- |8 E! N2 h3 C9 o. Q:param Thread_num:即将启动多线程个数,默认为1单线程' A8 F' o( m. k/ [7 ?
:param sem:协程信号量,控制协程数,防止爬的过快,默认为5% L/ f2 G, b6 G; \ y8 d/ S
:param cpu_count:运行爬虫使用多进程cpu核数,默认为系统核数一半- M6 Y* Z& Q8 `7 S( X
:param login:模拟网站登陆,保存登陆信息
' ~5 t' s$ g1 [# V( m) n:param Parsing:爬虫方式,支持re、xpath以及bs4方法: Y7 }0 Y U8 p
:param texting:是否启用连续爬虫,爬虫程序异常报错后重新启动爬虫,
: t4 g3 A T' F+ M7 V8 i' G 多次报错结束程序,默认否$ X4 o0 x, R4 j1 X9 I
:param label:选择器内容,字典格式保存,) b' a% @5 t9 V. J
字典值为列表格式,第一个参数为选择器,第二个参数为转换类型
( ]% @+ {8 M1 V6 V 第一个参数必填,第二个参数默认str类型5 o. X3 _" E3 ?6 j1 R s
:param write:是否写入文件,支持txt格式、csv格式、json格式以及pkl格式,默认否4 L* n1 L! H2 k8 W5 E- U! x+ J
:param next_url:是否跨页爬虫,选择器内容使爬虫继续翻页爬虫5 l2 f7 q2 a4 V" a$ e3 \
:param page:是否选择断续笔记接手下次爬虫处理,默认否4 R& {* i: w/ R6 Z
:param clean:是否进行简单类型数据清洗,默认否
! d$ C, ?+ W5 ^- w* E2 z:param write_sql:是否写入数据库,默认否
4 \- v+ u2 B: ?: B' X7 f 'host'默认为'localhost','post'默认'3306','user'默认'root',3 {: Y% R( _' a( E7 H3 [
'password':'密码','db':'数据库','table':'数据表',% I, q# v# ?1 T5 Y& [
检测库是否存在,若不存在则创建,若存在则直接插入,
% j! k& p5 t( N! B8 l G 检测表是否存在,若不存在则创建,若存在则直接插入) r+ D( j; K4 ^3 d9 m, X0 n! T2 T
:return True
6 W# }) n9 a3 G) `; B'''* v, H0 `, L0 f! P; b% C
介绍玩法
- d2 K7 X) W; S/ f接下来介绍的均为调用第三方库的情况下运行:
1 G# H( O. N" H s
: d, i$ k! C) L' gfrom simple_crawl import request' {3 r3 _0 Z9 u1 t/ D# c; a _
第一种玩法:输出源代码2 i* g0 r; _& ]
调用requests库进行源代码请求。
2 q) s& |6 v6 I: e) K( a& O x; }1 J D" b/ K* q$ a
特点:
: \4 B3 _& N* w# r请求失败则调用ip池处理重新请求访问,5 |4 \: [8 F' L X4 c8 J
出现五次失败默认网址输入错误。
5 A& M6 x* l9 P: Z支持text以及json字符串返回。默认text。* C( p: [! {& |$ M* N8 C* A: v
\' ]1 q4 a) u( D, |/ ]- j缺点:
% J" d Z0 s% ^3 D2 \8 x/ _暂时只能进行get请求,不支持post访问
7 @* `8 k E" P) y e2 R4 S5 O
( ?! e8 \) b8 `, b6 M8 F:return text or json
L, E# x; s5 s4 f3 @' u
" j! W! A6 @1 F4 xrequest.parse(
8 U0 _- ^; h. G' y/ z" K) M url = "https://www.douban.com/group/explore",' h X1 K) G z
type_url = "text". e0 r/ {. T/ B% _; ^
).run()' D' M* n3 y( j; ?9 x+ ]
# return text
. r) l. G6 R2 k* Q! }) c# m6 K* }: B$ x/ G- ~, m) j
第二种玩法:模拟网站登陆并保存信息
; d7 W1 v% t6 Q! f j. A调用DecryptLogin库请求登陆访问。$ p/ ]. A5 k! p `- D8 J# f: m
! A7 L; {( _; Q! J) j
ps:DecryptLogin库为大佬皮卡丘写的一个很不错的模拟网站登陆库,在此引用一下,因为单行爬虫原因不支持账号密码登陆,我将大佬写的二维码登陆使用过来了。再次感谢大佬开源7 z% C; {5 @9 p) k8 ?
在此放出文档地址
8 f0 c2 r" V+ E" k, pDecryptLogin库中文文档:https://httpsgithubcomcharlespikachudecryptlogin.readthedocs.io/zh/latest/
$ z4 J% }. _8 n2 g( m
) S& w" K# X) G0 `' o, b特点:1 m# ]- e% J8 j$ R# H6 z
将DecryptLogin库中二维码继承到此库(非二次开发)
& s* S7 L1 L/ t8 {( x2 _ }支持QQ群、QQ空间、QQ安全中心、淘宝、京东和斗鱼登陆(大佬登陆库中所有的二维码登陆)' f) x# D. A& G1 @+ W* L
保存session.pkl信息到本地方便下次登陆运行: T- a0 c n" ]" q) i. o4 p8 @
0 @! g$ F" t* H) F% v8 n7 `4 L缺点:2 W! r8 e- K2 ^% q4 X
session.pkl登陆信息过时无法自动删除。2 ]0 P% R3 {8 K( \$ r2 A# R
导致下次登陆疑似cookie无法正常登陆。
+ j7 L2 a* O3 }! P" T" P0 n0 T- S7 v4 ]& H
:return session
' Q! A$ }) X8 p
9 ^$ m3 b# n2 j1 M$ }request.parse(
$ l ]' L$ v4 N) o. } # 臭不要脸的推广一下我的店铺
3 u+ q& n& C: H url="https://shop574805287.taobao.com/",
$ [! U4 j/ s# o6 y" b! y/ F login="taobao"+ W s8 Z6 t3 | i
).run()& E2 M8 p: V3 h# [4 q
# return text3 @ Q+ o. x" `2 |' e; q' k; S9 w2 ^
" d% x' [7 }- @' q: d' R第三种玩法:爬取网站信息
" C; E# ~( a* {4 i3 n爬虫库自然少不了爬虫的过程: Y" m! ]4 Z( [' L* ^+ E% s0 A* i
: L- ^5 c; g) u# V& W4 M- X4 _( j
特点:9 G/ r6 G1 ?# J. X& d) E/ M+ B( ?! } g
支持re库,xpath解析以及bs4选择器。
6 Z, K; d& K1 t7 Q爬取方法为字典格式。单方面输出。0 o* S8 Q9 V8 x- s* K3 a+ A! O) k/ R
字典键为保存的字段名称。
3 e0 V. [% q3 x字典值为列表格式:第一个参数为选择器,第二个参数为转换类型。第一个参数必填,第二个参数默认str类型。7 |5 m7 l( Y' C, z* J7 `/ l/ c
$ L8 [+ E U; r3 t
缺点:暂无(等待小伙伴们发现)
9 x* w c' e" z0 U# ` _( r. { `) y
:return reptile_results, S( T, t5 G9 ^
, _' n# r; S4 \3 V% @- C
request.parse(2 l5 \: ~9 ~1 {+ {+ G/ s8 v6 r
url='https://www.douban.com/group/explore',
) L3 U- G! C6 J, G% R0 n # 字符串格式,选择器方法。( l% h0 Q* j. h, i- d+ D: u& w
Parsing = 'xpath',/ O: a6 k7 D9 ^
# 字典格式,参数如上。2 H- l" G) t8 u7 S
label = {0 R) S5 N% }& X) T/ U4 T* D# \ D9 c
'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],+ R. B5 ~* K- T# g3 E' r
'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],0 V1 Y7 L6 K# K/ f }& [0 A' ^
'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]: i, ]6 g2 t5 |, P" Z
}5 F- {0 J6 s$ ^9 [+ V
).run()
3 }. C( B5 E/ n& k# return reptile_results(list)
, Z: u/ N* Z- {. }1 L' l" C' p0 K- A# j
第四种玩法:自由保存信息6 N+ e! Q+ l4 n/ D
目前版本支持保存txt、csv、json以及pkl四大主流文件。日后版本更新将发布更为全面的保存方法。! E' L* [0 K$ g
5 N# g1 R6 z% h; ?$ U3 r0 E/ f
特点:
( [4 Y/ \* X' ]! Y3 l2 t写入文件均为数据格式传入文件。
, e0 D) w' J% C. U( m; g# w且输入格式规范方便阅读and省事。
$ h) p0 {6 J. ?& ^" d+ p2 l
' h4 s* M( C: m& z: ~/ @缺点:0 p5 E* r- h- b5 U: w
保存格式仅四种,
! K1 c4 X) S% n# a2 O+ B; I不方便用户之后读写操作。
8 x+ M3 @% ]: t7 c( h3 w- \2 V5 z4 M" C$ A+ d+ n4 k2 C, ?
:return file
$ [* C% u& S$ p
. X7 A. K: y" f/ W H' n1 r! Urequest.parse(% h8 ^+ }5 F; K0 X" ^% ?) S
url='https://www.douban.com/group/explore',6 R5 v3 M0 c- {# T0 K
Parsing = 'xpath',: R$ F: ]5 D% [8 @/ U" ]/ m5 a. o
label = {
0 z) r6 r! T" v9 q9 X7 V5 k2 R0 I 'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],% Q0 G! U* @8 f! l/ K; a, w
'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],! L* |# k! v; |# S
'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
& u" n4 B! Y: ~, L% }3 m' ~: e }; F },
5 Z# e% _0 \6 E& b # 字符串格式,具体保存位置填写
1 `" G( [6 J p2 y; m- N; F write='result.pkl'
& N7 G' K+ g1 m2 }).run()2 [' i6 m. g4 f2 ?4 l
# return file& Y9 Z+ x p, r: F: h) r* ?: n( W
7 s1 ^0 Q4 G# Q* j' r
第五种玩法:读取下一页 url 地址继续爬虫
! h1 }; {/ p8 t$ h( {3 D这也是每个人都担心的问题,仅仅一行代码怎么可能翻页爬虫。这还真能做到哦~0 \; e3 l- h! u4 O% r6 O
* C8 F' i) [4 Y" B: e: a特点:
1 c& C2 s$ g8 Q- N6 ^继承之前的Parsing参数选择器选择方法。
4 {: t5 h* M& N1 @7 A- m在这里可读取到解析后的下一页 url 网址。# {" y% u' G$ ]: E
方可继续进行爬虫处理。方便用户使用。8 }! [: g3 X" X
2 [3 m" F5 R+ p
缺点:
8 d) a) v6 [) d3 v% R0 a若爬虫时下一页 url 地址改变,便结束爬虫。
* x+ y' S0 D8 A8 X' Y只能爬取所给 url 地址中的信息。& E3 G2 U6 U: `5 B4 i4 Y& I
无法进行某一界面的多个网页爬取返回。
8 N1 \- J% ?3 I, Q9 P& ~7 B+ j9 S3 Q造成访问页面单一流失。& I( V* N4 T. R( B7 }3 r; s
9 p6 g0 e1 j: G# y1 I$ |" X
:return None9 G2 K F7 G3 t- F' V- k
- q- c) a' p4 g( @. E9 r
request.parse(
. C3 g H' W: s6 R& G0 G$ i1 o/ c url='https://www.douban.com/group/explore',# S/ q" I- M, X) W5 A" N
Parsing = 'xpath',4 ^7 g9 J! d6 b: V7 H
label = {/ }( m! R# R$ f5 J4 x# T& H+ H
'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],8 f3 G* V3 o* X
'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],
* t$ [0 I6 ]4 L: i, r, I 'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
! ?6 ?1 n* W0 h/ {% W" t4 _ },
! S0 }8 J$ c+ H2 s write='result.pkl',. f7 \3 g! A) `* P
# 字符串格式,根据Parsing方法继续请求下一页a中href
+ }' y' u) b& P5 v next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',
3 x! [* m6 Z% C).run()3 C" C2 i9 `2 F* s1 V
# return None
6 E7 @* F. y6 u; L8 Q: y4 w- N% ^1 d0 E6 u
第六种玩法:爬虫网页保存, f- }4 I8 T; g0 b; J1 n
听说过爬虫断续重连的朋友应该懂得这是个什么神仙操作。每次爬虫运行期间好好的,睡一觉醒来发现代码报错了。。。这就是个很难受的事,还不知道之前爬取到哪一页了,只能重新爬虫了啊!
m, T; h, |( F' o; X& M4 [% b* X4 O/ a
特点:
+ Y6 _3 {) T8 a# v5 r持续输出断续笔记。
1 x7 A# U8 Y+ R' M$ w将此次爬虫的 url 地址保存到一个文本文档内部。
6 A: n* g5 k" `% D K下次读取文本文档即可快速进行直接断掉的爬虫 url 地址继续爬取所需。" Q+ e' p5 Q6 L* ? B
) o: `: a0 G5 \; Z( f5 _缺点:
" `8 G. z2 j' L读取内容不单一。( V% g8 k1 X, d& |# a" O
导致下次爬虫无法正确读取上次爬虫留下的痕迹。
1 N3 y2 q# E/ o& V; r& U
: h2 R& N$ L" p; F$ d' Q' T; ~5 u:return url_file
, ]) s8 p: W/ ^' m2 c% | N7 @2 ]' t& @8 \, x
request.parse(
8 S- `# ]. g6 R4 d( r* c2 {, v* [! U url='https://www.douban.com/group/explore',
3 a, g- q0 F3 }, m z' f type_url='text',. l5 B7 B# g, Z0 b
#login='taobao',$ u/ `# j8 v4 s1 D$ `* X9 o) Q Y" g
Parsing = 'xpath',5 ~7 L$ L; @+ I$ B5 u
label = {8 u7 w' D) b" _& O1 A* o. V
'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
4 N# @5 s# f9 y6 I* _7 t# ` 'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str], G8 J* N" L3 T4 m3 P5 \
'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
. E$ A" A( S1 B1 m6 C* f, G4 \ },
# @( F. X, o# \' o) o( U write='result.pkl',
( }- `' z4 m. K5 z( @1 F5 g next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',
2 M6 z5 }4 N/ Q4 f! \7 A$ a # 第一个参数为是否需要断续笔记。
! `2 Q" j& z# ~2 X: w1 F # 第二个参数为断续笔记保存位置。
. w& \+ N& x' b* _$ n0 P; [6 o- H page=[True,'url_page.txt']
, u( J, E- X; p6 h).run()
, m' C4 U7 w0 _0 g' g; ^9 f% m" C$ ]# return url_file
+ _* B2 y, [8 s/ G. d% V/ j0 J% P7 M! L5 y' e
第七种玩法:简单数据清洗
6 O# h& r" j! p4 F" w6 @6 E* G$ E6 b数据拿下后,直接保存到本地有些大佬可能觉得很辣鸡,连清洗都不清洗就存入本地了?那得拿到多少废数据脏数据。那么接下来介绍一下清洗参数。% k2 d) F. q8 Z& J9 }! |
& ~) k; ?. p. Y( O$ P
特点:
}" o9 v7 w$ M5 |* Y5 ?+ ~- z本人曾写过一个底层数据清洗。
1 C# Z6 w* w$ B: H! a# i' G% q能将列表格式数据进行归分清洗。! e% y" n' J7 o! a2 }
主要内容请参考另一篇文章
4 W: n/ D) I2 ^# I: e" ?4 b如下连接:数据清洗
6 S" Z/ M( D+ W3 a; l# Q8 u- V+ Z* m I" a" C) r$ t; T: N0 S
缺点:
1 U/ Q6 k0 I- n$ h1 J数据清洗格式简单。
3 j$ `$ d* d4 b3 [, p$ m. p数据清洗内容单一。# c6 Y& K6 w! J/ K4 v
无法完全做到绝对清洗。- g- {1 O7 F/ A+ ]
有待改善。
' H4 t4 ^ Y6 ]7 e# d5 h+ t
! P) j; l: B; T8 D/ t+ `:return keyword_list, value_list# v/ |8 _9 }3 r" h- P. D; @; J
$ f) o' F4 W3 H9 Xrequest.parse(% Q4 M) p, X; W8 {
url='https://www.douban.com/group/explore',
2 W, Q0 |; Q+ ]5 y% j Parsing = 'xpath',9 p# L, `. c3 }- }/ {- _8 E
label = {# y9 a( [) ]* U
'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],; s# a T. j" D
'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],
M. D9 E2 q+ |) Q5 M% i6 d 'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]" O+ ?! D! v9 b, l" I- @
},
# I- f, s u/ a6 I' l write='result.pkl',# x6 `3 \1 Z/ M, \/ i' V! ?
next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',
2 r9 u- \1 c8 K8 ?2 f page=[True,'url_page.txt'],
2 f1 E( g4 @2 |3 e+ O6 g, x # bool类型,默认不清洗, M6 s4 y! c! H; w; J
clean=True
2 d- K, r6 F# N).run()- v; _* |; w2 \1 f7 u
6 D) r4 J" T$ c. F第八种玩法:爬虫存入数据库1 _. l" O4 \, L, Q
存到txt、存到csv、存到json、存到pkl,那也太low了吧。现在流行的数据库用不了么?那是不可能的。。" q9 @9 y ]; j7 Y4 N
1 f# K- f& a; m. q1 Z$ Y0 A* Z特点:+ V$ G2 R8 X8 @. n; x7 W8 y
信息存入MySQL数据库。, ?% f# ] X, c- _. B. I$ V
可连接docker远程数据库。- \: e4 A; k9 e. f% [ W: f
数据库的库名可以不存在。
! S: W* u$ a5 J+ N) H _数据库的表名可以不存在。9 J( U3 k$ Z+ O: s# H3 ?
根据之前传入字典键与值参数判断表类型。0 q4 f+ {' x6 E' f
自由建立数据表传入信息。
7 w, \1 C- |1 L4 B5 T( j' v# k7 J% |) L+ P8 u* i6 Y
缺点:
0 p8 _: v4 B( Y: u) s; `仅支持MySQL数据库。
% B. U. l1 m; w5 g9 }: R; q
, s2 F2 c3 ^6 n9 u:return SQL
3 Y$ f1 T0 a4 |5 G0 U) Q
6 f) S: I: n+ `( h* P) f- b, Erequest.parse(
0 U: Y1 y. Q1 R% K url='https://www.douban.com/group/explore',
- m* G7 q4 b% C" {; ]1 _4 `. r Parsing = 'xpath',
( I% W R/ s! O. H& ]/ f& L label = {
% {, O9 p) k1 I4 s& u 'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],+ M0 E. s4 R# ?* y& b6 D, S. P' a
'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],* W, q$ r- f3 u( s( T+ d+ o
'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]9 A( i+ |; e; j2 ?' S4 R
},
) v+ L, q! q" B! f0 @ write='result.pkl',) P' C) V# z7 o% R4 E& Z
next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',
; C1 T \/ [2 X page=[True,'url_page.txt']," K/ z8 ~5 V6 V2 W
clean=True,
2 w, S, o) \/ ^8 @3 Y # 字典格式,
5 b! t9 H- u- H; l # host可有可无,默认localhost; \6 z+ R; ]; _4 G/ `6 L" h6 X
# post可有可无,默认3306
/ `/ [# E" T7 B/ f4 _ # user可有可无,默认root
% `% `5 Y+ O" O; u% a # password必要参数,数据库连接密码
9 i$ h& Y7 G# ]3 D S% ]# } H- i # db必要参数,数据库即将存入的库名
% l9 w r* X# d) x; W # table必要参数,数据库即将存入的表名
* W6 x8 a6 ~& |! i9 Z8 } write_SQL={8 x1 k0 s+ B$ w$ l' c3 V1 L
'host':'localhost',8 G2 O& s7 R5 M+ Q) h
'post':'3306',
; M, ]8 L: _8 s* {6 F 'user':'root',$ s: F3 W2 o& `+ U
'password':'123456',
9 y1 z, _4 m# h \ 'db':'example',3 e$ V- I3 s/ z y( A- y
'table':'example': ?! G1 Y* p+ ]% b
}. G& w. g* \- m' E( m& o& f( G
).run()
0 D a9 I: g9 _& p# {3 ] W9 [% z% M4 n; r1 K: f" ^) V
第九种玩法:重新启动爬虫
1 I$ p' I A- g8 c U$ S爬虫最让人厌烦的就是被一个不痛不痒的错误信息给终止爬虫了,比如意外的远程断开链接等低级非代码错误,报错之后还得重新启动断续爬虫,就显得很麻烦。我做了一期爬虫程序异常报错后重新启动爬虫,多次报错结束程序。
# W8 e( \. [1 G+ x4 c' Z6 {( A* ?8 c/ j" g8 j' u Q3 U
特点:: C, ]2 f* c, T8 X
检测报错重新启动爬虫2 w, {+ w2 S# v& B
无需手动处理错误信息& ~ r7 D3 }$ L, n9 P. p$ z9 Z
: x) S& C9 V; S/ ~缺点:
7 J: J/ } h& P. T" s6 j v4 b. v6 ~4 z7 l无法收集子线程错误。
* E$ x# G, J1 a! r, r; X. x. X/ M; E/ t5 D& O8 @
:return None
( h1 ? Z% ]( ^$ `( D2 I$ L) @- @: D$ Q2 W. L
request.parse(
; I. S$ D( d5 ^0 e; Q X url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],$ Q/ X; r3 {4 c
#login="taobao",( j' v3 _5 @3 \# H
type_url = "text",# k* ~! g( ~4 M Z4 l- o( y
Parsing = 'xpath',2 ?% X1 j$ K) t
label = {- a8 P1 B: o- k4 y
'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
( s" p+ K6 `3 C1 F! x 'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],% w! w; E' u7 M, b# d0 q3 _
'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
- H; e' o+ O/ [6 a' D# }$ \ },# c ?) k0 f- V" |
write='result.txt',! b% T7 i! t1 ^! [- K
next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',1 [* w# O4 S' g6 o' C
page=[True,"now_url.txt"],, Q3 Z0 G7 `; F3 w) ~& f& O% D- V& e
# texting 参数为是否启用连续爬虫
% ]: p. V$ M- ^ # 爬虫程序异常报错后重新启动爬虫- _- S4 S' ^' I4 ?! K. l
texting=True,
2 ]2 [. i% w; R' Q) Y j/ s6 o ###' p7 i& l# B' I8 P7 U, Z
write_SQL={7 r+ @. P1 Y# x
'host':'localhost',
& z% {" h0 o+ @8 J; a/ B# J 'post':'3306',5 f7 j7 d: P/ H: i2 y/ |, `
'user':'root',
6 I0 R/ d9 t9 n+ T' t; @ 'password':'123456',0 v" K3 w v7 \$ S
'db':'example',
( o& g8 l* `2 k3 J6 j4 J) F, l9 e 'table':'example'; I2 s0 o6 D, W! `! n& `
}
' d9 H: B2 o* c0 @# {$ o; o).run()
8 i3 @3 I5 M1 J& l$ |1 _# s" l1 r) E
1 m' j( h) a9 I$ _5 h第十种玩法:多线程爬虫* C w) I1 x9 c7 H4 ^0 l3 ^$ i
特点:
5 `2 L, w$ {( E9 I1 x5 r. `爬虫速度加快,5 n O) A2 U1 B1 k2 A3 B- I
更好的利用了线程。 z2 Y0 S5 `0 `. k
% b2 J/ s" J( n! t
缺点:暂无: O5 b/ f( s, t3 q% l
% i5 _% E1 y1 b: ~2 a
:return None7 H$ M# H: _$ c$ m( p9 f
+ W$ Q2 [$ _8 Y: K' p( o
request.parse(
, Z) S8 h M4 w2 N) x- _5 F \' L) W url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],# q) q1 b/ U) m6 U. _
#login="taobao"," C- W. S: ~/ u! u; E4 T9 \0 j
type_url = "text",
" B. _3 | S) X: N. ?* C* a8 B7 \$ T Parsing = 'xpath',* T: M2 V' v, ~9 I9 C9 @
label = {
7 G0 z B! j1 @5 w0 _ 'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
2 t! B n( M' j1 I4 A 'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],
M3 V1 |% Q9 M2 Y& C4 p 'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]- |0 M: ]$ W$ I8 Q8 k k
},( g( c% x# |( X9 ~2 q
write='result.txt',
! }' t% J" X A$ C next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',6 ^' U* G' a1 c: f6 l6 ]
page=[True,"now_url.txt"],
3 K) p( M) l6 @ #clean=True,
5 H: L6 i/ Y' s6 t" C, e: P texting=True,
1 e+ X5 M3 s+ H # status="threads" 启用多线程爬虫( R8 D7 `' s6 _5 j7 j
# Thread_num 为线程数目,默认为1 单线程7 w+ N) w6 ` K W. k* b5 D1 k
status="threads",0 N: j) ~ u' F, d6 x. M* G, V
Thread_num=3,& K: Y0 P6 J) U$ W- a9 v
###
1 h- X( x8 t6 k* c; B/ s O) ]" X write_SQL={
8 Z) ^, m4 D# |: G4 A 'host':'localhost',
1 B0 B' P. d. }. B, ]% \ 'post':'3306',
, T e9 u( q+ L7 M9 o 'user':'root',
/ A1 z' q0 j; t" }; f0 F 'password':'123456',+ Y5 m) d- a' L/ h
'db':'example',
1 ?, d) ^$ J* q9 y$ s7 U 'table':'example'! W8 b* p' @$ D! S5 {8 i- |8 ]" N6 d" m
}5 f0 ?! i5 \% F, q
).run()
& P* \4 W/ B% L7 O$ \
( S F8 V8 A! `" S第十一种玩法:多进程爬虫
* G, @ I! m3 m$ M ^4 H特点:
" Y$ B4 @# Q8 P' X$ R爬虫速度加快,% C0 }: f. Z* N
更好的利用了进程。, l0 U, J/ q& i, F( }- `
# i, B; ~7 z! s/ R) I
缺点:暂无" P) R2 M. D) s) e8 |
- j4 ~6 i3 j: A
:return None
9 k, }4 C% J N- s" e% v! L% M: d. B3 | r0 h {
from simple_crawl import request
) p* l# u4 x) m4 m. Rrequest.parse(
! D, l& s/ E( T url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],$ y2 L9 r" d0 v, y
#login="taobao",! T/ O8 _9 D0 D5 E
type_url = "text",5 c1 ^# [6 e/ L( F* l5 R2 R, R) t8 b
Parsing = 'xpath',
" h7 I) r% T/ _2 u, g: B% h o6 W label = {* D# U0 l3 i. }6 f) ^
'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],+ s2 R- K2 u# e
'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],
; c, I1 ~/ Q7 Z% r 'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str], w6 I- \& x& r" q8 G/ U& g
},' X1 C/ ]/ i* N; C+ P+ ^) `9 J
write='result.txt',
9 m8 i+ Y& ~; w B6 n% \ next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',
1 {/ a' a& ^) x/ J' m page=[True,"now_url.txt"],
/ x j0 O% o- K" q) Z' X8 L #clean=True,, r/ c& s) C/ R# @% ]
texting=True,/ y/ f! _( G; u' N
# status="multiprocessing" 启用多进程爬虫 B' c( b; P3 Y+ g4 `3 L
# cpu_count 为启动代码核心数,默认为系统核数一半
5 a& m# b- ]+ q. S status="multiprocessing",7 a( G1 b' g! |
cpu_count=2,
0 f' ^. u( ?% J% r/ D% K0 W+ ]' E ###; _2 q& h, u+ \
write_SQL={
" h9 {2 y+ B6 h# J9 W+ |- g 'host':'localhost',
; i* q- u, T$ b4 s- t5 \ u 'post':'3306',3 [, W3 z3 L$ Z- f$ r6 T& f% m! G+ g
'user':'root',
- k) C, @! F/ }. G% l6 r3 ] 'password':'123456',
{8 b0 h( n, C% e" K A4 h6 e 'db':'example',5 Z) b- O8 k9 O0 H* }3 L
'table':'example'
% }1 q1 H w( X- r4 c }
0 [" V4 y" r/ r4 r).run()
; w7 r6 ^2 }) d5 [1 ]" K) w1 ~) S8 Y
第十二种玩法:异步多线程爬虫. L/ q9 v, A! u/ ?
特点:1 ^" V8 i0 x L# D# p% c
爬虫速度加快,
9 V& M/ F x6 g* s3 R异步使得爬虫无等待时间,
8 V* r9 I$ t7 }同时使用多线程速度明显加快。
) O8 ?4 S6 R* S4 w
/ K1 I% U. y; g- x" }# P缺点:暂无
0 r3 F3 z( k5 i! f5 e' b8 F. ^9 `
" Z7 d! S2 x9 u5 ?% y1 F; n:return None
% }- M( U6 S/ i( G% f y- h! N8 c6 `# _. D; |
from simple_crawl import request1 }0 w: J( o' \; D" \
request.parse(" c% `! Y8 L: R/ H3 U6 S7 [7 e
url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],& N- d2 J) i- V+ h
#login="taobao",
/ @4 a9 @) [. z( a: J! B" x+ x type_url = "text",
$ e# M R- Z& u N, U Parsing = 'xpath',
! ^/ G: x+ _6 J' q% T3 H1 W label = {; \. `* O5 y7 {/ a( r2 n5 I1 e
'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
+ e8 `' v( X& g! j$ ~; S/ Q 'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],
5 u* s% A% F r$ |3 a 'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]( p+ B% m8 X- u# d7 n: k
},0 Z1 T2 k6 i& Z6 z3 h7 b
write='result.txt',8 U5 c& C2 R) q9 o4 i
next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',( z8 E( V- l" N; ~) }
page=[True,"now_url.txt"],
! ^7 x* |: a# O9 A( J* u #clean=True,- x- g# e# w0 |& C! e* L/ j
texting=True,
- ~) H& a7 k8 m+ b2 g& b' W; t # sem 参数为异步引擎数目,默认为5
, b8 I" W/ R$ k # 其他参数同上8 q5 A$ f( Y$ I& r( e! V( `9 K
status="aiohttp",
: \% k3 [0 Q6 |. R7 A6 B" s Thread_num=3,$ I8 [* M6 }; V7 q) v- b
sem=5,
/ F) a2 _8 K% m. ]/ v2 x7 @ ###
# t* w2 u' ^% B9 H write_SQL={
0 n9 U$ A/ X5 G0 w& ^3 l 'host':'localhost',
' ]+ a" F) Y3 G5 d6 s2 e- l 'post':'3306',% s% c' e2 Y/ y
'user':'root',
7 G$ O; u" x# o! c7 T% D8 S 'password':'123456',6 T: N- N( Q1 a5 t, M. ~/ Z& F
'db':'example',$ P y2 g( f1 d
'table':'example'
' x5 H( V& p4 _ j. h }; r5 C# [, Z! W' |# m% S4 Y3 {& {
).run(); v9 ]2 \( G2 {5 V7 W0 p7 B
4 i" O/ i3 R' ], h* t3 W第十三种玩法:异步多进程爬虫8 U) ?5 S3 \* Y8 J; \9 o
特点:
" E% n) U% b4 J' o1 F8 q' V爬虫速度加快,9 S. K; {- ^' }" ~3 E
异步使得爬虫无等待时间,8 k1 g7 f, W- P; W+ T
同时使用多进程速度明显加快。
! O# R6 H0 L' e0 x* Y- g! i) L% F9 O! e( B) l9 r7 F/ w6 Y
缺点:暂无) n, X1 O0 G6 I, |- W) }5 ?( i4 ?
3 Y A! ^( \) t0 Q$ f:return None' D+ n* _; k5 k- D8 i0 e
: A+ U/ p/ B1 T" \. bfrom simple_crawl import request( X3 U4 X6 U, E0 l+ S# N5 Z
request.parse(- L% K1 M- D F) K/ u' _7 x
url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],: k% Z" q- N' u# ?. F) g
#login="taobao",
! {6 v; l8 ]0 k) a4 K E! W type_url = "text",2 y# \5 U+ t" \9 ^9 Q& g7 h- _' C
Parsing = 'xpath',
" T& S% i) n1 X) u+ P+ z9 U label = {1 j: f2 Y' L! A. z9 q* w" R) ?9 t1 { r
'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],( {# i# {, |: ~& G: p& r9 V2 V
'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],
' b5 }: ~8 y" y1 j( X) ^ 'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
9 K8 Q6 b) [6 j% @& P+ D },
! D* E$ x2 r6 q# b7 E. v' M5 B write='result.txt',
5 k" n- r) ^# E5 Y* { next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',3 ]& @5 U: j4 p6 d
page=[True,"now_url.txt"],
' l1 K$ v" o1 E( w! ^3 O #clean=True,$ }. Y1 |% s% K% s7 W: j
texting=True, L' G# a1 V, g4 B1 g6 s3 ?/ C
# 参数如上0 M3 d& H n& h9 \& |8 A. v
status="between",# k$ e% }# t+ O$ Z8 J" G
cpu_count=1,( Y( |) F. m# _- s5 }% s; G7 M v
sem=5,
5 ]2 z& M9 ?) H- K ###
6 s7 z$ ^. V- M) m1 f write_SQL={
$ p' _2 `6 H7 P5 @( w/ p7 t 'host':'localhost',* @1 p- a b! [' P% J* J
'post':'3306',
6 j7 w# i* g/ r3 y 'user':'root',
: d* U: g1 K$ v& E3 t 'password':'123456',
8 a/ [6 q- R4 P# \ 'db':'example',
' U' R' X. j$ w9 u 'table':'example'
- W' H: J" ~7 o/ H ]) t5 k7 D5 y3 s }
! L4 E5 s* u# X0 I! m4 x9 t) Z1 p).run()
4 ?7 Q" P2 b* @7 T6 u0 s) X, |9 p' r% ]9 d+ H& K) ~
! X! u& V) k3 _0 y/ ]6 }1 S5 H8 O4 f
功能介绍完毕🤞
' g+ _, _3 s8 g! H& A0 Y6 l最后还是希望你们能给我点一波小小的关注。& x% d# j8 |, ^' R; [; H
奉上自己诚挚的爱心💖
) Y2 d7 _& ^- O9 G) }3 o————————————————
; s+ Y! Q* E1 c5 N% W) [版权声明:本文为CSDN博主「꧁༺北海以北的等待༻꧂」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. S6 j! d# e( U0 t2 _ n" {
原文链接:https://blog.csdn.net/qq_45414559/article/details/106005684
# i% Q' P& @" P' ^7 v, H! z% C6 u0 F* P/ x) s. _3 t( {
- w7 I6 F7 w+ [: @/ r d9 V
|
zan
|