- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 564701 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174633
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
% s+ f& d f* F; [& W% G
& S9 d9 H. H: [& k f7 Y
3 {$ T3 C# ~& l( N手把手带你5分钟搞定爬虫(聚焦爬虫) . z3 `; C) o- k7 f; F+ t5 \% `
. t2 H! f# r+ o1 S3 c爬虫的原理
6 P9 k4 K5 X, {5 b7 _
/ p+ ?, @- ]2 K, P; g对于很多刚入门的小伙伴来说,了解爬虫的工作原理是非常重要的。只有当你了解了它的原理,你才能结合实际情况写出对应的爬虫。下面我将以通俗的语言方式来介绍爬虫1 G) h. x# Q6 I$ U, q' t R0 P
把互联网比作一张巨大的网,那爬虫就是这张网上面的一只小蜘蛛,在互联网上面有很多的数据,各种各样的数据,我们可以把这些数据比作是被网粘住的小昆虫等。爬虫的作用就是去找到自己喜欢的口味,然后把它带回家,可以储存起来,也可以马上享受美味2 u) ?4 P) U0 J& Y7 s, i
所以说爬虫分为三部曲:
& {2 B; ^6 i3 E" s2 x1、明确你自己喜欢什么口味(制定需求,明确你需要的数据类型)$ e+ k# j- X7 D2 e. b
2、去找到你喜欢的食物的位置(得到目标地址)
, {3 ^. x( m6 U* @3、把食物搬回家去(解析网址,获取数据,存储数据)
' e( M: b. L! E% g它的整个流程就是:(简单的通过request请求获取数据并解析获取数据。以下都是固定化格式,可以照搬)7 s, F! v0 t- H0 b
a、导入需要的库 requests
# H1 N) F' e3 ?# O. r5 V6 y, W$ ]2 e; U( Z4 D% s" F6 o5 R5 [& a0 L
import requests
( B& A" w/ @: W# {0 Y1; h2 |1 z# L, y' A! }+ Z% ^
b、明确你要获取数据的网址(这里以百度网站为例)
7 t" ]# {) Y, p+ D% r& Y& i& s
! @% ^$ m* N+ N, }url = 'http://www.baidu.com'9 a# u! ]) _' ?8 R2 Z" m" a
1* V- Y. U' u# _; q9 {" D! g& L
c、创建请求& G9 ^/ R; a8 e- M* R, M% Z
9 A9 R+ y. q* B8 N ?response = requests.get(url)
/ k/ F; ^ d2 l5 L5 I9 [6 h1
% W. W) _; L. b5 gd、测试请求是否成功(在实际应用中用的比较少,正常情况都是可以请求成功的,网站对于访问外部信息的爬虫是不会做出限制的)
8 V+ Y7 k" {* l# N* b* S* K' A1 p) G! n
print("状态码:",response.status_code)
' E* c4 A8 p! k% K4 R# c1
2 |% Z0 W* y. Y, e当状态码为“200”时表示请求成功;如果不是“200”,很大可能就是你的目标url写错了,核对一下url1 d+ X; u" L+ r; q7 Q, J
e、得到网页源码7 W& l6 ?2 g# Z# B n) T2 X5 x- W
) A; O- N+ B7 n2 Z% ~
print("内容:",response.text)
; o/ q" }9 z s# e7 w) }5 u" V7 `1& h9 x) J& e# y2 ?
response.content是response.text的二进制形式
! o: m' K! v6 X% v# `" T
' T- o- T1 B. m3 m+ [4 C: Z至此,一个简单的爬虫请求就算是完成了。, b7 D z$ b+ P: _1 V
当我们请求目标url并获取到response后,就需要进行下一步:解析网址并获取数据
2 G9 Y/ F- z' Yf、解析网址
, i$ I# z! _) d2 G" T* J刚开始学习阶段,我们最常用的两种方法,一种是BeautifulSoup,一种是etree。其中BeautifulSoup是最常用的。以下将对两种方法分别进行介绍 (以下方法均为测试用例,实际当中应结合自己的实际情况选择应用)
3 u1 h; ^. |4 `; g/ J% L% T$ l! H! nBeautifulSoup:2 T: e$ c6 m/ j V- M/ M; A$ P
首先导入需要的库文件:
- W+ `+ S/ O# b7 p' Q* b5 z$ `$ h6 O9 J. Z' l
from bs4 import BeautifulSoup
7 f/ s$ h: i) p: s. Q" p1 U; `4 X1
8 [, |8 z: `3 q) O4 v" u然后对上面请求得到的response进行解析:
0 P) O( V" w( A6 ] P& l L- T4 }$ M! f" e% L* Q* |+ K7 Q
html = respone.content.decode('utf-8')6 O4 F* E: m- Q$ Y) o' b# @( b; ^
soup = BeautifulSoup(html, 'lxml')
' H! q+ f8 P" L. j5 O% w1
8 a2 b2 G9 L1 T; c) S2' G9 |( L; m: \, X3 u
以下是BeautifulSoup中比较常见的方法,有兴趣的朋友可以去一一测试:; ~" y) C" x: I/ ]
# 获取head标签6 G9 a# S, {! \' O: V! j/ s" |
print('head标签内容', soup.head). p& ?2 L. O% H4 K5 Y' [+ O
# 获取title标签
* I4 }8 J( P5 Q- L+ mprint('head标签内容', soup.title)9 n' \6 ^* L) m
# 获取body里面的img内容9 P% v0 N1 t4 W8 y% N2 @
# 通过点号的方式只能获取 下属第一个标签(即获取soup下面第一个body里的第一个a标签的第一个img标签)
7 e! O/ g6 ~: ^, Wprint(soup.body.a.img) - c- Q8 O W2 _5 k
# 获取所有的img标签 使用find_all()搜索整个soup对象+ Z$ @ e( e) ]; l% v% e
print("获取所有的img标签", soup.find_all('img'))
j7 m% ^ l ^# 获取标签中的属性src地址
) n( [5 w8 }1 T0 y, @" Mprint("获取标签中的属性src地址:", soup.img['src']) # 注意:英文点号都只能获取第一个值. Q) L) C Y$ h& V
8 [# P" y3 J, P" {( ~
* X5 ]' G+ {8 l, B6 L2 O% w4 f
# 获取soup的name
( }% @$ I4 i7 K2 Wprint("获取soup的name:",soup.name)
) a* [" d! a& S$ C9 @# 获取a标签名- H$ x+ b* R6 h$ `3 T9 a2 R0 y
print("a标签名字:",soup.a.name)3 q' d; K8 z% o( {: e
tag = soup.a
# L6 p4 F: p5 K3 b2 P6 `print(tag)
% k3 n' D: [+ {# 修改操作 a标签改为b标签
$ \4 s* `3 o: i( }5 Mtag.name = 'b' # 赋值后<a> </a>变为<b> </b>6 s$ E$ m, Y5 T. I U7 ?8 H) R3 D6 L# F
# 输出修改后的内容! P. J0 ? r2 f1 \+ i
print("输出修改后的内容:",tag)
0 { [4 ?- J% {, v: D; p. @# 获取全部的属性 attrs
* }* W0 {+ X* A8 w: Zprint("tag对象的全部属性:",tag.attrs) # 只能得到当前标签的属性(不包含下属标签)* `) r: f% r! h: U
' k* Q% P! U1 ], ~0 S5 Q$ D# 获取属性的class的值 根据键取值 [* t" p T, Y6 i
print("获取属性的class的值:",tag["class"])
3 _; n0 {* ?* ~! \" e
. l. X$ I s% Q) o' b- Z9 }& v1 [% u$ _8 ~0 c# C0 c
3 e* I0 h6 b3 Y, F4 u0 [
+ T/ W5 i; i6 h! U0 N2 u8 F& t, B"""针对获取的标签属性可以进行增删改查"""
, U. F+ i8 }+ d- S* m$ \1 X# 修改" ]4 f. x5 k8 q5 s5 ~
tag["class"] = "Logo"& g9 U) n) W. s1 h: X/ [
print("tag对象的全部属性:",tag.attrs)4 ~, Z" v6 ]- z0 {( ^8 b" C
# 输出属性
9 B3 K8 M: t8 c. X& T. Yprint("获取属性的class的值:",tag["class"])
0 _/ T! }, Y! V# r- s# 新增 属性id 赋值logo1 W4 f7 i6 [! ~% H
tag['id'] = 'logo'
|! b* X( U. E. \: {% v; m" Fprint("tag对象的全部属性:",tag.attrs). d7 b7 r0 e" S" l. b
# 删除属性
$ \& Z; ]' i6 }% [3 [ pdel tag['class']0 g( O8 {% k1 T% ?' ?
print("tag对象的全部属性:",tag.attrs)
5 J* V8 _; J* { s4 |/ o$ ~# R4 P. F' a: v% f" G7 Q
! B) m+ m( m" m* `
1 Q2 v* {5 @1 Q7 X: F* R4 g"""针对内容操作 (只针对标签,对属性无效)"""
7 j/ h4 k/ w1 W4 h: W5 H3 }4 N# 获取title标签内容( E6 k* c& p6 ^. g
tag = soup.title
7 X2 I O9 f9 X+ I# 获取title字符串/ ^8 U9 Y9 w% k4 K1 z
print("tag对象所包含的字符串:", tag.string)# D& O/ M$ ^. ?
print("类型:", type(tag.string))
4 U7 n& c( K' ~+ G' \- u j# 替换内容; _$ @+ q7 X8 ~+ h
tag.string.replace_with("你好")
& i S# C: J" Pprint(tag.string). X& e$ x# X9 d! a( w
# <!-- 学科建设 -->
$ |9 h5 F. Y! N! z( v- Y1 t9 X# 获取注释文本内容# Z0 G7 u2 _. ?4 U& u
markup = '<b><!-- 学科建设 --></c>' f0 [ A% \7 ~' ^% ^/ N, Z8 B
soup_comment = BeautifulSoup(markup, 'lxml')' z B' ?, u; {+ A2 s
comment = soup_comment.b.string # 以markup第一个标签作为关键进行搜索" t$ ], B' R8 }; [9 l
print("获取注释文本内容:", comment)
/ Q( |$ W* r& k* P) `# get_text()& V% Q' q8 K0 O* K
print("title的全部节点:",soup.find_all("title"))
) s- u) z- D; R/ t7 w! g$ nprint("title的内容:",soup.title.get_text())
/ F& {: f7 D# t# U"""查找ul元素标签"""
* c# i( r" }+ \3 E+ G* e6 h# class是关键名,匹配时后面必须加下划线_
1 I# ?% m. a5 p, b r# tag = soup.find_all("ul", class_='menu') # 按照css类名完全匹配2 t7 R8 T( H! e$ \- a
# print(tag)
' |. p5 } Y; ~% ?9 qtag = soup.find_all("ul", id='menu') # 按照css类名完全匹配0 k& }# ?8 q; T0 ^! C
print(tag)- @( b2 l8 D& d4 x3 {
# 查找名称为a元素的标签内容
3 S! k% K+ q7 @ d" ?3 gtaga = soup.find_all('a')) @; N! ]4 Y# }( L# ?& a
for tag in taga:+ x7 a) `# U+ Y/ A& I8 i [0 r
print("查找名称为a元素的标签内容:", tag.string)
6 R, p$ L$ J# a9 w# get 获取属性信息 获取整个页面的img标签图片和src属性值
% o- A, n2 h" j& w( Y& Ztagings = soup.find_all('img')# g: c7 o& e- y* _ u! {
print(tagings)0 I& l+ V' E \: N( d
# 循环输出图片地址( F9 h4 m+ H5 \& u
for imgsrc in tagings:* [4 b3 `% h3 I. d
print(url+imgsrc.get('src'))5 H/ m9 H* Z* o1 V9 X3 Q& @
0 B; G/ F% J" r4 l, Z
""""属性只能做为参数,所有的操作只能针对标签"""
: X+ O' Q w1 _' F! W0 n7 D
* K8 f) H) ^( W6 P# cetree方法:
5 Q2 h0 N% S+ i" Y7 o导入库文件:: T5 b0 t6 m9 R5 v
. ?$ Z! v% t* @2 |" ^$ l
from lxml import etree
, B$ W, u9 s! R2 B* N" V" p1' k1 u, K+ W2 w4 N' o7 u
解析得到的response对象;
8 m8 l& p5 \4 L Y9 H" `# {4 v3 f+ b: T- A- T! C1 r3 G; K
# 设置response的字符集
" ~9 ^6 w5 c0 s4 W5 b6 ohtml = req.content.decode('utf-8')9 Q! ?! r5 ?0 x
# 解析对象4 v0 B% n" U2 l0 x
html = etree.HTML(html,parser=etree.HTMLParser(encoding='utf-8'))
( E9 i* p _- a; b/ j7 u& B6 l
% \5 h+ v$ Y: `" A5 f' E常用的方法:- w0 P$ f; J6 k2 A+ I
* r& m- @+ n) f
- r8 O( b- T- ^# 定位head节点(元素)
3 m. V! F& o. ?. r% d) Kresult1 = html.xpath('head')- q0 _" o/ Z* _; e* ^5 G
print(result1)" h, ^- d8 J; u
# 定位title节点
; K8 ~/ B: z, h2 e3 Nresult2 = html.xpath('/html/head/title')
7 j7 M9 J4 e: S# T V& D' M6 sprint(result2)8 y" S1 ~; b* E% ^! n* E3 i9 |
# 搜索节点 title节点
5 _: @6 q" [- r, L% h9 iresult3 = html.xpath('//title')
3 _9 B$ k+ k$ fprint(result3)
( P* }& ?4 W1 A# 搜索title内容 text()得到文本信息) k0 S3 s' u% S' P" E
result4 = html.xpath("//title/text()"). w7 A# h+ M' K% N) { X& B$ r; Z
print(result4)
4 W6 L5 F; f' _6 ] _# 搜索div节点
( ]& w2 J- F3 t( H9 hresult5 = html.xpath('//div')5 m' l7 m0 C1 |4 \
print(result5)
) X4 N, `9 S7 w9 n$ Z6 k# 搜索div节点 并用class属性定位5 ^) F! @3 i7 K% K8 R
result6 = html.xpath('//div[@class="news"]'); C/ e+ I( p; c4 L
print(result6)2 [3 ?. R: \( p) p% [
# 搜索div节点 id属性定位) Z* O% V4 u# H- _
result7 = html.xpath('//div[@id="news"]')
& w2 A# N: j |; B# jprint(result7)' a/ i5 g( E8 n/ l- H
# 获取列表span信息
5 E7 n* h: G2 ?$ V4 [8 `; r% y- Htext = html.xpath('//div[@class="news"]/a/span/text()')
$ J! q. f& j9 `$ {$ s- B2 uprint(text)
% z1 n! r$ q1 | n( x- D2 P
1 o7 x1 |% Z& J; c% n8 s- |! }g、通过上一步我们得到自己需要的数据后,下一步就是将我们得到的数据进行保存7 E: ^9 _ h7 s1 x# y" c
保存的方式有很多种:/ y1 \6 Z( x& R6 K7 T9 |. c7 E# o
1、保存至文件
: e# X' D) k* e+ Hcsv、json、text
4 f, _1 D3 H( p! O: H D5 Y2、保存至数据库
6 N5 w- u" F7 Q" }% W# xMySql、MongoDB、Redis 等 (目前主流的为以上列举的三种数据库) 关于数据存储后面再做详细介绍
5 Y, P) P' m, X) q+ D& j. X9 ^* N) Y6 M) {) C2 ?
6 n% U! w. `; w# d
————————————————
4 f: H8 ?6 S* _% h' w7 V版权声明:本文为CSDN博主「royallucky」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: d2 z- K/ c: g: V% k6 q
原文链接:https://blog.csdn.net/royallucky/article/details/1059304732 U+ K5 `' D) ~( n+ \+ l
) R6 N5 d6 s. Y* ~ k" P: H, a* D, G
|
zan
|