; b5 h3 r6 n; O2 m, ]; Y' g2 s X+ f7 H
' A4 \: d6 O" P9 K7 @, ~3 J
' d8 r/ o; s' N( {1 s
! ~9 E9 r- h6 t. S" g+ p文章目录# q& `8 U6 n: ~5 j2 \! b
requests ; [/ D7 g# E% l* @" m: wrequests基础- p9 ]! M4 B N' ?) M/ r, ^
requests模块发送get请求 e9 a. g+ t3 f# `
response响应对象 ; H k6 H% v( X6 ]; g4 \( A. \response.text 和response.content的区别 % U! X* F. A' R; O) M" E解决中文乱码 * z' P& {+ l) J! N* [7 Z& V. s- hresponse响应对象的其它常用属性或方法9 ^( H, y8 s5 n
requests实操 4 N% G6 E/ i6 \, U/ D4 ?* wrequests模块发送请求 * p( B* S7 M, g) F6 c5 X# I发送带参数的请求 5 s# b2 t- M, S, ~, m超时参数timeout的使用 % b$ q o+ |; e g8 e$ H: f! ~% yrequests发送post请求的方法# a* C) R# ?4 t' Q% \3 {
BeautifulSoup 0 H: q# a& R! K7 [+ q% C; |常见解释器的优缺点 # d* l! x2 b& w: O' H5 Y) n( P常用操作 / G" J" d/ R/ x. i几个简单的浏览结构化数据的方法 8 `7 a. V/ L0 V; w从文档中找到所有的< a>标签的链接 . a$ \: u( A8 p$ F' C" a- M在文档中获取所有的文字内容) G" O- Y1 A/ _$ [3 {' v. Q
通过标签和属性获取1 K ]( y, G1 g- i- M
Name属性- u+ E0 n. L3 _# I- x
多个属性& H. e2 M7 [$ @
多值属性 S0 B- n2 c7 l5 a可以遍历的字符串 # N0 \, |/ ? o, D. F+ C! r注释及特殊字符串 * G7 G1 x% Q m% `. m* J+ K遍历文档树4 N9 D' x2 s5 a% U: ]2 F v2 j* B
子节点 / z3 E8 _4 j `+ [2 h5 {find_all方法" Z, w+ g* P" C i1 @3 C
.contents和.children 8 o) [, i2 C2 Dselenium2 N2 G) D& ~. T+ O M
selenium介绍7 ~1 D! I6 c; I- g) x
chrome浏览器的运行效果 ! d0 L5 q/ f1 P6 l `. z, C1 t) ^phantomjs无界面浏览器的运行效果( E* u# w9 j0 J
selenium的作用和工作原理: z' m# |& y( h- n- `! X' f
selenium的安装以及简单使用 & t ?/ P% Y) [4 r$ @- P. X/ t& Jselenium的简单使用 9 B( d0 C6 T6 T* J2 i4 W; d9 Alxml 2 f5 d1 X% R' N常见解释器的优缺点5 j6 b0 y0 v" x7 {: g- _+ \
* t* g. @# f, V+ ?* l
' L0 w9 T9 k3 @
& R4 t0 j+ x3 J. {
/ x1 I+ C! c" c5 {) ^/ `, K/ D0 W常用操作* @, _3 p h3 Z! }
安装方法' Y& e; w7 x A4 \5 c% f
/ z- o9 c" N7 o* a
* B- ~/ g8 q' S+ wpip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple beautifulsoup4 ' O$ G' M1 c; W: L7 s1 s+ d1+ r' \* Y9 U; A! i& h3 g1 Z
导入即可 & C1 B! ~, A1 B2 _- U8 G( @ 3 O6 Q, w: o5 { " c+ M6 ^/ D+ _; b( B6 j, Lfrom bs4 import BeautifulSoup4 R4 ^$ t% _$ S1 @; T5 j
1 4 C5 ^2 o' w0 l- ehtml_doc = """* r# w' f# J5 @/ e; Z% }3 N& C
<html><head><title>The Dormouse's story</title></head>/ V" g5 @* c9 \
<body> , B6 _0 Z9 n* c! j<p class="title"><b>The Dormouse's story</b></p>8 }; n# y; \9 L/ ^7 M7 F
) y* e" r' L- G& O! a i
) m" B4 V t9 y5 K' w$ m8 q
<p class="story">Once upon a time there were three little sisters; and their names were # x, `, B/ Z' M8 f$ O<a class="sister" id="link1">Elsie</a>,0 ~/ K4 s. \& n9 V+ u; K- N/ x
<a class="sister" id="link2">Lacie</a> and / @( k2 Q8 T+ R$ K; E, S& a/ L<a class="sister" id="link3">Tillie</a>; ) d D: ?; l1 n( m- G( K# _and they lived at the bottom of a well.</p> % \6 k( I1 {3 p5 W# g4 @8 [" R9 \; W7 p( h
4 {; V/ z! n' _' V<p class="story">...</p> & Q( E1 \, u) i! F- A3 l""" " p: Z0 X& S; p6 K1 J: @1; J: w$ Y3 S1 r) K
2- f- `1 K& O$ b; a" N! m
3+ o9 K) x6 i, J7 s
4 3 v- ^# R( `% O52 w. C4 T! l6 m9 X
6 / w% {7 N4 f; a4 O8 o* [) e79 O. W# R' n4 k" J6 ?
8 $ [- l" I4 F2 S- j/ X( H93 o+ Y; {, T. W8 ~
10 ) f: v: P6 j8 S. Z- M113 O: a9 e, O. k- N: C) }
12. h2 k! Z( j; C; ]: K. e! K
13 ' u4 d$ j% G* _soup = BeautifulSoup(html_doc,"lxml")7 j# Q; m6 y" Z L9 ^
1 ; e0 a* ^7 H! T; }7 X5 B$ q9 Q几个简单的浏览结构化数据的方法 ( T* z" U7 f4 l5 u# @5 }soup.title7 p6 ]% i1 u, c, ?
1 4 b; s, F6 k" O3 C) y<title>The Dormouse's story</title>, m1 w/ M5 ?# b2 j+ w
1 ) J/ y: D. L e- s0 P+ bsoup.title.name& H* Y( d \- J; T
1" O. }0 [$ j; Y. |5 s
'title'6 D" ]! R' I) g/ j$ Z
1! A2 S u( j& I
soup.title.string 8 ~7 X/ t: A, r3 K8 y1* r0 U# t' Z: a/ B/ ]( |
"The Dormouse's story" 1 F1 E! @/ ]% I1 [0 a5 o4 {/ a14 k2 _1 m* P; `; s% l( c. Z/ M# t9 O
soup.title.text B' N$ \3 Q1 x6 o/ Z1 $ q) C" ~: ^5 a1 a7 h5 M2 L( D"The Dormouse's story": U2 ^+ P- \" J) r0 N
1 ' q" x9 P- ]% k. @# M }; Usoup.title.parent.name / B. u3 M& p# n% o1 4 p0 T! Z; s3 P+ ?'head' 5 \ I$ w! G9 v6 K) h; x7 \1( K; r9 R/ c6 r& W! F! `
soup.p 0 T* Y* W) y% o. }1) m! r( B) x* T7 J7 J
<p class="title"><b>The Dormouse's story</b></p>6 g" v2 e$ N9 y7 B* \
1 2 H$ a0 k3 J9 Q! o+ P8 isoup.p.name! B1 ]7 O# z- j7 G) N
1+ m% v N0 R, I( a
'p'1 }7 I& t9 c' C' |. s" }
1 7 @, @9 Z/ v' b& i% i- t% i* \soup.p["class"] - K: k j/ E# l& U1 7 d6 c6 g4 J* P['title'] " t: _5 t2 G# p. i/ K1 3 X4 M4 V: N8 H6 Ssoup.a: n5 u* q" E9 _7 i& `
1. n+ F! M5 }. `4 e( x) S2 ~3 X6 X6 L( j
<a class="sister" id="link1">Elsie</a> z6 S/ z) ^8 e; b18 q! H- J/ Y3 [; H9 W6 Y
soup.find("a") ( O% d- u3 g# C5 H1$ s2 e/ l. r* a4 _
<a class="sister" id="link1">Elsie</a> ; g1 P6 h: H0 g. `; ^. L* E2 K9 i' v16 ^' c. ]8 w' E1 h; f3 h- B
soup.find_all("a"). y/ Y) B+ l! V: T6 Z
1% d% T, H x' G' K v) p9 y9 F
[<a class="sister" id="link1">Elsie</a>, 8 p/ O" ]3 T. j2 K% }; b <a class="sister" id="link2">Lacie</a>,7 |3 h3 F3 p0 q
<a class="sister" id="link3">Tillie</a>] 1 i+ l6 D) A _, M1 " X) l6 \2 ?, j" C1 w) O4 @* x2 6 n. P8 `( P% c4 U38 s* S% y. _2 P: v) R: T
从文档中找到所有的< a>标签的链接 + E0 n& x, S! I0 P# N& m9 K+ ofor link in soup.find_all("a"):8 k) c5 e& C' b3 P C7 g9 ~% l
print(link.get("href")); N. p8 E* m5 i
1 8 P: ^9 t0 r0 e7 ]8 I+ _2 % W% _6 q! c4 p: k9 @! Ohttp://example.com/elsie # y& S1 G) \! rhttp://example.com/lacie2 J' ?; ^: v; j/ O/ L9 V( B
http://example.com/tillie/ y, h: Q2 U' X6 Y
1 - [# M) F! g: t- I$ }2 ) R5 T1 W! P) o" W6 Q; i38 Z- X) \$ [2 G) E, ?
在文档中获取所有的文字内容" {! y/ c" B0 ]* g8 w; C! i
print(soup.get_text()); h+ P1 L i6 W( Y/ m/ u- s
17 j+ ?5 B, T" k5 i: G& I8 T' ]! Y
The Dormouse's story1 ^: G' a+ ]# ^0 b
; j. a: m; B' w o. K& A4 j 4 V9 i- x% J7 k) H) {The Dormouse's story! G7 {2 _2 q( U) \
Once upon a time there were three little sisters; and their names were 1 n) f8 z- Z" h2 |Elsie, & n9 y+ @7 [4 r/ R* [Lacie and( s) \# h: d$ S: _. V( T3 b
Tillie; 9 ?6 T* O: G7 f( R) Eand they lived at the bottom of a well. - d' R' k$ U6 J7 w...$ l7 r7 Q0 k0 n2 j% X4 T
1 7 T6 T, f1 C) p5 l3 R& b. j2 3 i: Z# I/ l3 }' i8 p3 & P. ]& s; q9 A8 y- s9 f4 : W1 a' o' C- N2 A51 B, |! n, ?/ A) \
6 2 c/ x3 `2 `. H8 r75 Y4 z% V# K7 t
8 % V9 r- ]* u- d9 - u% F1 z2 N8 ] h. b" J& Q+ [4 T/ H" F! d
! S: Y7 ^+ B. H5 Z
]1 R) g& F$ k. w" R+ B通过标签和属性获取9 ?$ K9 [8 a/ e: l
Tag有很多方法和属性,在 遍历文档树 和 搜索文档树 中有详细解释.现在介绍一下tag中最重要的属性: name和attributes . I& B; E) i* K% h1 z/ N9 ~6 l0 E! Usoup = BeautifulSoup('<b class="boldest">Extremely bold</b>') $ |( w& b% c3 ~, x7 atag = soup.b' W! Q5 f( h1 B, }0 \- [/ e
tag8 {' M6 I$ Z) z4 m5 O9 N; U( y$ u; o
1 $ p8 Z) q6 R' G3 ]2 L8 i' o5 _5 d7 M
3 3 `4 W/ Y5 `! ^2 P- f<b class="boldest">Extremely bold</b>* [) J/ x' i8 _/ \& M
15 a7 m' t# W6 @+ O3 O
type(tag) 2 [+ p- `, |- M1 ( p( i! y% {* M/ f. N& L: xbs4.element.Tag4 \: S. M/ j/ e( L A3 d
1 ; `% t) K7 x4 z1 C- ? t0 \3 A8 oName属性 6 r+ V6 t5 j* @; S4 d每个tag都有自己的名字,通过 .name 来获取:; N- u1 F- j8 }% C) a6 Y
tag.name " a0 Y& O- N8 V. d18 w' Y, o. f! Y3 B' ~" E
'b'$ e0 s' K9 e9 I/ q: |
1 * n, X4 _2 e* U8 A+ n如果改变了tag的name,那将影响所有通过当前Beautiful Soup对象生成的HTML文档+ x6 e: d( O5 Y/ l1 ~1 Q2 H
tag.name = "blockquote"' q7 ]( a* D. B3 _$ {/ f
tag , L$ K+ @" x1 Z# ?: V; R1' d2 \ z0 d9 A% g1 s C6 o
2. d( v% X1 d# C) L
<blockquote class="boldest">Extremely bold</blockquote>' `% u1 X# [6 B9 h) {+ A
1 6 }- y& {$ x! O6 k* K$ Q3 i多个属性 . r5 q t J' t% H3 I4 j一个tag可能有很多个属性.tag 有一个 “class” 的属性,值为 “boldest” . tag的属性的操作方法与字典相同: 5 ^, X4 p* y6 p- A! ]/ otag["class"]" _6 {3 T, E* _* M' }5 {
1 B# Q% w7 ~& V/ E( o/ P['boldest'] . c; T, X& X' P5 x1) b1 o) O; e' I* ?- }+ W
tag.attrs X5 c) }* [5 u/ R# F# @
1 S2 d! I: B" o# L{'class': ['boldest']} , [7 U& o: g3 L: f% p* h1 + {% a6 R- g1 s" Y: }) t+ E8 `tag的属性可以被添加,删除或修改. 再说一次, tag的属性操作方法与字典一样 % u) v7 d0 m) [" wtag["class"] = "verybold" ! f' T; s4 M+ ?" z" B/ j% dtag["id"] = 1- G$ _& G, X( U1 H
tag& |0 ]! j4 q+ `4 p) w3 | Y# w
1: ~% ^ l" |, {/ b: F' `, m
2 9 k0 C( R/ G5 D, r2 t0 \5 s' i9 s K3 ' ^! O6 }' C. D5 m. u' G. w9 y<blockquote class="verybold" id="1">Extremely bold</blockquote> . ]6 ?) c5 H7 m) F: S1 ' b% n* l0 b* Y2 k3 rdel tag["class"] 3 C+ u* |1 `4 l H, Btag& J3 I% D/ u1 _' G
1 # p8 T6 u+ k9 w27 S9 `0 J- a- a+ g+ n. B
<blockquote id="1">Extremely bold</blockquote>6 U: z* w2 \8 T1 ]4 o6 k7 Y! b
1 3 W6 @7 x5 Q6 a) b+ k( j" K9 r多值属性 9 o3 A! o S7 r4 Rcss_soup = BeautifulSoup('<p class="body strikeout"></p>') , q/ \# X& _' b9 ecss_soup.p['class']8 f- \" h% K" @% [2 q& l
1 % Z6 e$ N. v- B2 0 \7 \7 c% Y0 b" B( \$ H['body', 'strikeout']4 p% |% T% o/ w, ]# x+ ]
1% O. d' x" |/ j& y. {4 W
css_soup = BeautifulSoup('<p class="body"></p>'); |- d1 e" s F* q: Q Q
css_soup.p['class'] . m, m4 k' d- I1! K R1 G- U5 |8 s% I
2 4 m# T; e9 P0 u8 }['body']* ~7 o' g2 G6 Z* W& Z. Z
18 b4 v. |3 Q7 }6 J4 {3 C2 |
可以遍历的字符串 & g* K S" L) ?2 K2 ~字符串常被包含在tag内.Beautiful Soup用 NavigableString 类来包装tag中的字符串: # _% p) v+ _5 @tag.string + u# r$ O/ z8 a G1 ( b3 t+ G" T. q: p'Extremely bold'6 k' D$ L' e$ B) o6 }7 U
1 U( ~# e# `- j# O. R
type(tag.string)" [, j+ W0 Q5 ]( t
1 % q0 q% v4 t) p/ a! G% [* Nbs4.element.NavigableString - v4 m2 j& C1 W9 ~% k5 P& R2 d1 $ R3 b( {- J# W1 j6 m& D一个 NavigableString 字符串与Python中的Unicode字符串相同, $ @& Z: T; G# b0 w并且还支持包含在遍历文档树 和 搜索文档树 中的一些特性. # i3 P" `. x: D0 R通过 unicode() 方法可以直接将 NavigableString 对象转换成Unicode字符串: ( v) C0 L5 E: C( w) @- \ : M1 C5 t3 O0 J0 m, T+ z: [% e' X5 N3 H2 U3 S' A9 h
tag中包含的字符串不能编辑,但是可以被替换成其他的字符串,用replace_with()方法 / N3 h* P7 S* N- x5 E, a' t+ C 1 }* }. ~) F: z, S9 T$ C+ e 7 v; O& x4 ~8 ^# O# Ntag.string.replace_with("No longer bold") & a0 v$ C8 X# v) ktag * e% @0 H' F% h% k1 p' t+ \% T1/ M/ L* V6 _; {. x) k& G8 n
24 K+ A. S% S$ z: |& ]- H6 u( D- T
<blockquote id="1">No longer bold</blockquote> ; k8 Q4 J. l- k7 \1 ^1 5 J _7 M, z/ ^注释及特殊字符串* n7 N2 { ]2 k6 f) _ K4 r
文档的注释部分0 W" T3 ]1 T+ g/ f$ F5 P' Q7 @
markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>" # i6 B9 Z0 E. `, Xsoup = BeautifulSoup(markup)/ ^/ `# L i, f2 C- Y4 U, |) ~$ Y
comment = soup.b.string( s+ n& w% R9 I
comment 2 R7 `; R! L4 X% ^! {4 j2 n1 / s) |7 m, v: F/ o2; z/ M/ i. P: J
3 + o* M: J. g5 J8 ^7 ^' i5 w4 ( G! x* b1 b# {* B8 d+ {'Hey, buddy. Want to buy a used parser?'6 ^$ E" G4 B, X: j
15 V0 z& W7 q! C- v- O. T
type(comment)9 a7 W- T: p: B- N; ~' A$ Y
14 S' j# p) H, K- ~
bs4.element.Comment+ \! c1 A, N9 ^) H( S( n
1 : X; C; e+ w; H$ Z/ IComment 对象是一个特殊类型的 NavigableString 对象:! a1 D) W5 }; {3 g
comment. ?) N0 z; {4 |
1 ) F% m# W9 k. q$ W'Hey, buddy. Want to buy a used parser?' ! n$ C" `- S7 M. A: c1 . l! }( n) y: }# H# v但是当它出现在HTML文档中时, Comment 对象会使用特殊的格式输出:' q& H, E$ ]$ y8 S: O
. a6 j C% f7 O1 v8 p. I
# X) j9 s, r& a# v( r2 J) k3 u. uprint(soup.prettify()) - g7 Z9 y6 P! k4 [8 \: ~1 D; H0 k+ W3 w2 W
<html># j& k: M) |- w# F
<body>6 H: z5 u, G# t3 w- ]6 Q
<b>5 n+ ^5 b8 e2 o( I r5 b
<!--Hey, buddy. Want to buy a used parser?-->1 Q( o# I+ F" y$ T; c6 b
</b>/ B$ B. V8 V l* w+ ]4 S
</body> 6 [% ?- `1 b& r! Y: Q2 _4 ]</html> N. ^5 \( _# e$ C) u8 r/ h1 : i: e- O6 |( _6 `9 t/ J8 {; p2% n& q- d$ n2 m ?+ e8 l& H
3* ^3 [8 t! N9 l+ |: F
4 8 G4 n2 S4 c( }5$ A* N) V# r0 m" x5 L5 ~- |. p, ]
64 r" C. R: i3 ]( s6 l6 Z, L
7# P% S% D8 y4 g" ]
from bs4 import CData) [& A, z, x2 @7 T: }' d3 w( a+ H2 I
cdata = CData("A CDATA block")9 [! |5 y# r) I; W, j8 a
comment.replace_with(cdata) * r) v$ v7 C" jprint(soup.b.prettify()) % @% Q! n: Y3 s4 v& y O1 * w7 i4 G4 `. d2- H F( X' m( i) f
38 U' p: q! Z4 x6 Q2 Y, P
4$ k. L. x# `- O4 d# F
<b>1 Y9 b0 I. T/ t7 f/ B. h
<![CDATA[A CDATA block]]>; u; u b9 ]/ x" _, l
</b> / X: v% v3 g/ U' s) ^) P" |& O- u7 n12 h* o) u9 P) a. B7 k
20 c( S* y# U: w6 ~
3$ n7 Z E( }3 U3 d# t: f$ g
遍历文档树+ i! k1 m! [7 R4 s; H
html_doc = """ ( W6 T1 S% z( N<html><head><title>The Dormouse's story</title></head>. a3 j* |: A0 Y9 Y% a
<body>( K- {' k6 M3 Q0 T: R- v
<p class="title"><b>The Dormouse's story</b></p> * ]$ e- Y2 R" Q, O9 }+ K# s0 z' I/ n6 W1 @3 e( G4 ]# _" Q
4 \4 ]: T6 y0 V
<p class="story">Once upon a time there were three little sisters; and their names were- a/ x8 ?# f) z o
<a class="sister" id="link1">Elsie</a>, * I$ }. }7 B3 L<a class="sister" id="link2">Lacie</a> and 8 p- Z6 U& M4 o; X+ J: p<a class="sister" id="link3">Tillie</a>; 2 q+ `0 m; ^8 r; B9 Zand they lived at the bottom of a well.</p> $ R# d$ m2 ] {3 ` W" D- z& [" ]( e( V! h
- S. g, _# Q: X& y9 `, c<p class="story">...</p> : P e; {: o1 e ^" {3 e"""8 Y; D) ?6 O b: M
1 ( f* i" p5 Z( q, T. b- p+ }25 F& E3 u1 [/ n, C* m) g, I
3 ) |/ T( b. t9 ]40 ]1 i. D+ e. Q" F. A& G
5 7 U+ Z; j0 f' P/ [* V60 j5 \4 f8 |+ W# J
7' Q! X- G! c/ z2 J% _: G
8* s! m# |0 G2 |; a
98 ?) a( y u$ H5 V& m1 C
10 4 r* m4 C) ^" i9 n3 J111 z+ C- {/ S# u7 b
121 v2 U; d4 H- d6 e
13 " l( N p- L1 B) t7 Sfrom bs4 import BeautifulSoup" D8 [. I; a7 N
1; N* i, f: G% O2 J4 T, r
soup = BeautifulSoup(html_doc,"html.parser") $ Z$ O( A3 p' N5 H% P1! Y/ t5 ~) n4 J6 a
子节点: j$ A7 A' `5 m( t/ z+ f4 F8 e- w
一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点.Beautiful Soup提供了许多操作和遍历子节点的属性. 0 f1 M; j! C# F q& A4 \7 k; E( K/ P7 l, ]( G# `4 F% t. V
% ?. @4 V Y% i
soup.head ' u0 Y0 X* ^. f! c$ R1 L1/ n; F, Q3 x% Z4 v
<head><title>The Dormouse's story</title></head> 8 h' y+ ?8 H4 @1& {; C& T- G7 K# f9 G3 E6 W' u% F
soup.title( O( H$ |" {- n5 `+ N: s2 O
1 9 X. I+ s, K; B3 J( C<title>The Dormouse's story</title> ! [+ {2 h" y+ R5 m* O, \1; I0 k& V5 A& N1 {* ~
这是个获取tag的小窍门,可以在文档树的tag中多次调用这个方法.下面的代码可以获取标签中的第一个标签:, s# s: ? I; I4 S' D: \: y( t
2 ?2 I, u. D0 O8 i; L) ~7 l4 g
; S5 B# y* R% M/ w- S* K! G
soup.body.b . v) r- N/ v, y0 J$ H1 ; g# y) y; ^2 `2 c<b>The Dormouse's story</b> 2 k8 y& s4 v+ L* D& H1/ n, Q w; E3 z( \1 t
通过点取属性的方式只能获得当前名字的第一个tag: ! j* G3 j7 b0 W2 c+ e! M1 H8 D1 W # N4 h+ Q5 A$ e5 c4 f* h. r. C2 E4 K/ j% s4 h
soup.a% |5 {( v9 M4 v" _- o
1 & ]0 b7 @) D9 O<a class="sister" id="link1">Elsie</a> 9 I$ u. e* b1 Z& I/ n' U8 |' N* Z1 8 j( e, d5 [9 ^& b& s2 c4 R+ ]find_all方法 8 i3 D8 w F5 ]9 z/ {/ a如果想要得到所有的标签,或是通过名字得到比一个tag更多的内容的时候,就需要用到 Searching the tree 中描述的方法,比如: find_all() 4 [* s, S* r, B% z2 s + e" m$ G% K s1 M8 h. }+ q+ y ( M$ ^; X2 N3 `: V4 B) Gsoup.find_all("a")7 y l) v7 s' q1 ]7 l8 Q
1. X9 \8 J2 s2 }- }# C
[<a class="sister" id="link1">Elsie</a>,$ u6 }4 p7 i, `- V0 F# v- E
<a class="sister" id="link2">Lacie</a>, 2 `" |8 J, G, \ <a class="sister" id="link3">Tillie</a>]! A7 M* t- `" @7 g: Y, V* d
1 $ x- K+ z Q+ h1 D1 f* F2 f2 " E( W6 i. v4 K- t3 b2 A; ?3) W" Z2 ?" d& q/ V5 N/ Z
.contents和.children' M# J1 e; O) {$ O. h
head_tag = soup.head- T7 M' _- [( d/ k
head_tag5 s! Z3 P. M. r0 Q7 J
13 U- F; A1 t: z+ Y+ j( z8 N
2 , C8 p7 T, x2 j<head><title>The Dormouse's story</title></head> 8 f( O! t* F9 g1' H! _+ g3 e: A4 O. G
head_tag.contents% Y+ j# p) c! d/ \7 p( `& e; w6 n, D; [
1, P% W2 D' Y% J1 z7 Z7 n
[<title>The Dormouse's story</title>], l0 X3 H+ d0 {; {7 F$ n- W$ [- k
1 $ t) ` O, ^' p' ~( P$ I# ihead_tag.contents[0]8 F f! \: w2 a9 X3 u
1 - W% u; j! N9 W1 t/ @<title>The Dormouse's story</title> - r, g* v$ O" ^/ Z6 V# E1 : R: P/ Y" ?# j9 L3 Shead_tag.contents[0].contents * X& Q' ^% u) ]! {1 ( }6 t3 t- n* y6 E! [- W["The Dormouse's story"]$ X/ Z; j; D+ [7 K+ \
1 3 g. A) J( G1 e" |, ]6 kselenium 9 T# l* j( V' g3 t j % A; Y! r6 C6 c; n* [. t$ h6 G6 c/ }5 [+ q. r4 ]
- Y C# F. i2 n+ y, i( q: n. ^2 Z7 C% q6 v3 j1 Z
selenium官方文档 https://www.selenium.dev/selenium/docs/api/py/api.html' Z c0 E8 G3 N0 b
( h" m5 `/ X% h. b0 \ 0 h* H- a/ ~! u9 s I% T) c9 Zselenium介绍 L% `) k( F, u" x; W- ~
chrome浏览器的运行效果 - ]' A$ h) E9 o$ }. p在下载好chromedriver以及安装好selenium模块后,执行下列代码并观察运行的过程; w- u' u7 Y' f
1 G6 t6 V) ?# R$ S y: g