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