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