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