掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 95065|回复: 48

[教程] 用一个简单的例子讲讲怎样从网站上扒数据

    [复制链接]

该用户从未签到

发表于 2014-6-17 19:21:42 | 显示全部楼层 |阅读模式

1 l# B# O2 r. A" c一直想找个英语单词词根和前缀、后缀的词典,主要用来辅助记单词
: [8 ]+ Y, s. M4 y/ F; s比如entombed,如果知道en-,知道tomb,这个单词看一遍就记住了,
5 M5 d1 h) }3 `1 ^  n2 w6 e7 m* M8 U, ]有点类似汉字的偏旁部首7 U6 R; C0 k7 W7 V/ B
找来找去,觉得prefixsuffix.com这个网站还不错,收得比较全,解释比较简明9 t( f! J* ?+ {. L
但是总不能整天老挂在这网站上,得想个能离线浏览的办法6 ~% U* T  \" w$ ~7 B& s: w
他家倒是出了个app放在appstore上,卖18元,说实话有点小贵,人家SOED6才卖18) H' T8 m* U1 t+ a
这还不算,最要命的是从2010年以来这个app一直没更新过,究竟是不再维护了呢?还是已经完美到不用再更新了呢?
! F, A$ O; D) b8 W. Q% k7 d' U$ ?8 S要知道这几年ios都有过几次重大升级,万一买了和ios7不兼容,闪退怎么办?岂不是白买% z; M" c9 ^: z$ K0 U

' K- O  J" `. c0 T9 j% k% V; L于是想到有没有可能把他家的数据全给扒下来! K2 ]+ Z2 G9 F+ O; b1 @* {
运气不错,这家网站完全没设防,扒数据的整个过程轻松而愉快
" V) Y; k3 `/ P, L+ q5 o. o现在就把这个过程详细讲讲。遇到类似问题可以照猫画虎,把附件的代码改改就能工作
2 s) v7 [; `/ G我尽量写得比较啰嗦一点,让计算机小白也能看懂
' f9 k1 m. P) i) p5 S9 i) n
; V' ?, |% D0 R! w& y$ _: A一、网页的构造5 `9 {5 R+ J; i4 r) }8 _  ^: g0 c
这个网站比较简单,和词根相关的网页就两个. B0 Q1 M1 H# l- @* i
一个是rootchart,点开是张大表,列出最常用的词根
+ S. d! S7 p, t+ e' x  Thttp://www.prefixsuffix.com/rootchart.php?navblks=1011000
% i% _! k! c8 d还有一个rootsearch,点开有个search选项,可以自己输入词根查询6 {) W0 Y5 B7 }8 W# J
http://www.prefixsuffix.com/rootsearch.php; F2 Y( o% \; c- t
# v0 L7 P: p* `* t
二、先搞第一个网页6 h& }0 @* R5 h  M1 _
地方找到了,如何下手呢?
: L- g& R+ N5 z5 [: G第一个简单,直接用脚本请求这个页面,把返回结果接住就行
  1. & b( Q2 I1 [1 K9 j
  2. url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'
    $ }: ?  T. p; ]2 e! F, o
  3. req = urllib2.Request(url)2 i) K" `$ ~( Y% ?; _
  4. response = urllib2.urlopen(req)
    " X. h. C: v4 A/ a* H6 }% X9 E8 }
  5. page = response.read(); N7 r: r! B" F" h
  6. print page # 打出来看看返回结果究竟是啥玩意
    / N1 Z+ T  i& f
复制代码
给计算机小白扫盲! h# v, D# z8 X8 ?
互联网的工作原理是这样的:用户向网站发送请求,网站响应请求返回数据
9 l9 P5 v. M2 j比如用浏览器看网页这样一个最简单的操作:
! C; K+ m# O. _" j, K输入一个网址按回车,浏览器就向那个网站发送请求;网站返回的网页数据被浏览器接住,经过解析、渲染呈现出来4 z7 `" |2 Y+ o6 T
视频啥的也是一个道理,只不过这时候返回的是视频数据,不是网页数据" L& M9 X4 m" _- _7 {4 k; G
这里用脚本发的请求,网站返回的数据自然也能用脚本接到

2 v/ t; P) {4 K1 B7 j
# x5 R3 _8 x0 C5 L网页数据拿到了,真正需要的那一小块数据在哪呢,这个可以查一下网页的源码,右键菜单->审查元素,如下图
% q7 o# Q3 `$ h" h. y: Q9 |: Y) A9 v% S& h; C6 K
5 N6 [( x: H, O/ p  s# l
可以看到那块数据就在这个大表里面
  1. <table class="affix">...</table>
复制代码
在那一大篇网页数据里把这个表找到,把里面的内容给抠出来,就是一个超强的python库:BeautifulSoup的拿手好戏& V1 r6 i; Z, l- S
(这个库使用起来非常简单,文档也非常完善,有不明白的尽可以去这里查询。这里不再多说。
- w  U0 N1 K- O! x* a5 ahttp://www.crummy.com/software/B ... 4/doc/index.zh.html
/ c% n1 j& v0 i+ s3 i3 @* j, Z* y  ?0 U: s# Z( I' v& a
于是有下面的代码

  1. ( g3 p4 ?4 C3 Q6 ?* Z% H
  2. soup = BeautifulSoup(page)
    * h9 [% p* }* i' P7 b
  3. tb = soup.find('table', {'class': 'affix'}) # 这样就把那个大表给抠出来了
    2 [* T6 j$ i7 }! d! E
  4. # 然后再一层一层的剥! m& _, a9 o( u, [, l
  5. if tb:
    : Q2 N* y# e" y
  6.     rows = tb.findAll('tr') # 所有行
    ; z& \* j+ V* {
  7.     for tr in rows:3 M0 y$ f) O9 ~5 i* R/ y
  8.        tds = tr.findAll('td') # 每一行的所有列
    6 J4 s& b) V% o' e. L1 R
  9.        if tds:. w8 K$ M4 b/ H) }3 W8 ~2 r
  10.               。。。3 V. K% G/ M2 y- v, G+ K
复制代码
第一个网页到此解说完毕。
( z5 b& Y3 {6 X# \! _2 _! ]博客类、或者外汇牌价,基金公司的每日净值之类的公告信息,都可以用类似的办法扒数据. M0 Q9 w$ }$ ]
! p# T/ H' w) V& z; x9 Z
三、再搞第二个网页
5 X. k2 m% m8 p这个稍微有点不同,它的工作原理是这样的( c8 ~' [- e3 K) O/ m! _; a7 e" S
用户输入关键字,把下拉框和"start","anywhere","end"这两项选好,点击search按钮,! W0 n. X' ~& ^/ m/ {
这时候浏览器会向rootsearch.php这个页面发送请求,捎带着还要把用户刚才输入的这些数据给POST过去,
! c1 D5 C$ N, J9 V) U/ G1 Hrootsearch.php收到这些用户数据,才知道要干啥、吐出什么东西回来
% T* g6 U  d, s页面url是已经知道的,那么这里的关键问题就是:浏览器究竟把什么数据给POST过去了呢?
! W, q: s# V4 {9 T* r% X还是要查一下网页的源码,如下图  ]  b/ V( K  G+ x1 |( G) f. d
4 d4 x4 e2 E: G* J6 }- I! x

) u, s' L( M& K/ e0 D7 E- S可以看到这是一个form,里面有这几个东西正好对应着文本框、下拉框、"start"……:
3 r* h' x+ |5 A" ?1 ufield、find、stype$ R1 w% L% R9 |  G1 X# n) F
还有个hidden的东西searching,不晓得是啥,不过没关系,它的value是固定的yes1 m: w  [/ K- T2 n1 @% S0 q' ]
给计算机小白扫盲
$ U. a1 F' y- P2 [$ G$ A4 ~  Oform叫做提交表单,用来把用户输入的数据提交到网站后台处理
0 [- |) t: K/ ^' E4 g文本框、下拉框、"start"……这些叫做网页控件
% B; i1 h" q3 m! J; Q! Q, H5 k3 ?注意它们的两个属性:name和value,这两个东西都是要提交给后台的,这样网站才知道用户想干嘛

  X) `1 W$ w! B$ c* e3 I* J2 \* B8 x( u$ Y+ b; U
搞清楚以后,于是有下面的代码
  1. ' }% P) B2 G9 p- B
  2. values = {'field': 'root', 'find': 'ex','searching': 'yes', 'stype': 'anywhere'}" G' I/ ~! c1 v/ I0 `7 K
  3. # 这里模仿用户查询ex这个词缀,输入‘ex’
    # ?! e) k0 K2 ?# D
  4. # 扒数据自然是出来的越多越好,因此把下拉框选成root,单选按钮选到anywhere6 r8 K5 B  t  v/ r4 S! M- [3 h
  5. # 实际上为了扒到所有的数据,我写了26个字母X26个字母的组合,anywhere/start/end各查一遍
    7 R4 x9 N/ K) p# m
  6. # 一共发了26X26X3次请求,比较暴力,这种丑陋的代码就不拿出来现了
    / K# T6 V( x; \5 ?
  7. data = urllib.urlencode(values)' u' }- @' _) T
  8. print data # 看看变成了什么,是不是很眼熟?' }& d5 g! S9 ]6 H( G$ L4 e; l
  9. req = urllib2.Request(url, data)+ V! C; }( ]6 y2 k) u( V" J# @
  10. page = urllib2.urlopen(req)' o: j" r# |; f% B7 m
  11. print page # 打出来看看这回又是啥玩意
    5 U) j6 a1 q* P% a: g" {
复制代码
这样就又把数据搞到了,接下来的流程和上面第一个网页的BeautifulSoup那块开始往下一模一样
$ r( f$ _' }4 ^/ d& h- e注:
) r! h8 f1 O+ i; q0 S* b像这个网站这样每次检索后刷新整个页面的做法已经不多了,& i3 K, |3 I7 g3 X- {4 N% p
最近大量的网站使用ajax技术,网站不再返回整个html页面把整篇全部刷新9 H. W* L. U; n7 k+ p
而是返回一小块html片段,只刷新页面的某一小块,比较环保) b- U2 E, b* l+ b' j1 ^
或者干脆只返回一大串数据,用网页的javascript解析、生成html,这种就比较头大,数据看着头晕' ~0 d+ n# h' X, r/ N5 P) P

- V8 V0 _0 y$ M! Q' t$ h$ C第二个网页到此解说完毕。
" M3 o6 Z) p# K9 o- L; T. G网站登录类、论坛自动发帖类、订票类、考试报名类、抢沙发类……等等原理上都是这样实现的( \0 o0 R  k+ ~3 x5 M" X
2 ^" G! F, L" i% l) e

" N4 F* Z) n- z. [% [看到这里你应该想明白了,为什么现在各个网站都要限制连接间隔、用图片验证码
" q1 [4 S7 O; M* g0 V3 o7 o还有用短信发验证码的,有些还搞了数据加密、随机数什么的。。。不这么搞网站服务器就要沦陷了
. q' w, N$ j$ u; h" y' Z6 x' H所以上面的代码通常会遇到网站的各种阻挠,让你抓不到数据,需要你和网站斗智斗勇* i0 F# k0 y, a0 Z! ?' f
像图片验证码这玩意最近已经都不太好使了,有人收集大量的验证码图片建特征数据库,一样能突破网站的防线$ i. n1 j$ |8 ^
于是最近很多网站的图片验证码搞得极其扭曲,以至于本人用肉眼看半天都输错,+ s: ]" j7 u, ?/ ^& q' Z
已经到了人类都无法识别的地步。这种网站估计是留着给外星人用的。3 ^. j) k% D$ P  {

  h2 I+ D3 h- n) \- J3 @" Q6 O% l

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

2

查看全部评分

本帖被以下淘专辑推荐:

  • TA的每日心情
    奋斗
    2018-7-17 21:49
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2018-7-28 13:22:31 | 显示全部楼层
    首先,非常感謝樓主。
    4 b. L/ n. @  D& k" M我獲得affix2.txt后,分別用MdxBuilder3.0、4.0X32、x64創建mdx,4.0版都沒問題,但3.0版總是創建失敗,
    9 P( @* D' C, i1 |% M/ _Done!) }. P. C$ [* J' s" s2 T
    Original index size = 0KB, compressed size = 0KB, compression ratio = 314%- i% e& C2 b3 F! J0 k; O6 e
    Time used for this section: 0 seconds
    6 q1 p8 I3 r. PBegin processing data contents...0 x+ l5 ?! e0 `) @3 R1 {
    Failed to read from source file:C:\Users\frankly\Desktop\affix2.txt for record(line):1
    " k$ e8 B5 s) t! J8 rConversion failed!
    . e% f, y8 s. `9 J/ ^請各位指教,謝謝。
  • TA的每日心情
    擦汗
    2022-3-12 13:24
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2016-10-12 16:46:54 | 显示全部楼层
    bt4baidu 发表于 2014-6-29 23:27- |, w1 G% p1 b* O. C
    这种静态网页按我上面的说明毫无压力吧
    ' u2 ^- e9 I( C; `1 I8 t5 C, D6 [比如http://www.nsii.org.cn/node/80/A/Acanthus/Acanthus%20leu ...

    1 I4 q5 {# x7 ~9 o( u楼主问一下您的 wish list 上的 英语电子词典都找到了吗?
    7 J. ]0 q! N( v! B辛苦了$ B8 l" T( y' ?- s
    如果找到了能不能也给我分享一下? 邮箱[email protected]
    + }& C) `6 ]* N+ s\thanks\a\lot\  :0
    . y5 z+ x4 \6 }9 S0 |5 q:)

    该用户从未签到

    发表于 2016-5-16 18:10:45 | 显示全部楼层
    楼主发出来的代码好整洁! 学习耶
    7 W+ h# V: v) ?
    & _! s. t5 z5 v3 o/ L$ e( A* t2 f0 M请教一下 26x26 字母的问题。能不能教教怎么捕获异常?提交上去的两个字母可能是没有的,比如 xx, 这样的话,怎么处理?
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-17 20:14:43 | 显示全部楼层
    辛苦了 ,O(∩_∩)O谢谢
  • TA的每日心情
    无聊
    2018-6-29 05:13
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2014-6-18 00:15:43 | 显示全部楼层
    ?我用火车采集器在采集百度百科呢。采集了1000000多万条了。制作了4.2万条,300多兆,到时候做个词典在电脑上查。估计做出来都有20g了吧,800多万条了

    点评

    我当初是保存的gzip压缩包. 20多G. 解压后至少70G. good luck!  发表于 2014-9-1 16:29
    冏,20G,硬盘剩余空间都不够了  发表于 2014-6-18 10:05

    该用户从未签到

    发表于 2014-6-18 02:15:21 | 显示全部楼层
    好贴要顶!
    3 r* D7 M4 ], u3 s: s3 X
  • TA的每日心情
    开心
    昨天 06:41
  • 签到天数: 2570 天

    [LV.Master]伴坛终老

    发表于 2014-6-18 09:10:56 | 显示全部楼层
    以前的百度百科2012,有30g,现在已经不更新了,如果楼主出新版,那可是大好事啊,预祝成功!

    点评

    个人感觉百度百科编得有点糙啊,不如维基严谨。这里有epwing格式的各语言版维基http://sourceforge.jp/projects/boookends/releases/,一直在更新  发表于 2014-6-18 10:04
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-29 10:00:52 | 显示全部楼层
    楼主,请帮忙,这个网站的如何扒http://www.nsii.org.cn/newquery?qs=*:*&fq=kingdom:Plantae ?

    该用户从未签到

     楼主| 发表于 2014-6-29 23:27:41 | 显示全部楼层
    wenlishahsa 发表于 2014-6-29 10:00
    . g% V2 `7 z( w- t4 N$ K( t楼主,请帮忙,这个网站的如何扒http://www.nsii.org.cn/newquery?qs=*:*&fq=kingdom:Plantae ?

    ; I% @5 I" n4 Y( Q2 \& V7 Y这种静态网页按我上面的说明毫无压力吧& ^3 N7 r* s  {1 ^! e' I0 R! e
    比如http://www.nsii.org.cn/node/80/A ... hus%20leucostachyus
    # N7 S7 N$ P0 a  B6 d这个页面,找到
    $ t) Z3 @. Y5 q9 Y! w  l% @<div class="content clearfix">% G7 b' I$ H* t4 R5 c# }
    ...1 |! g' }* h' P* \
    </div>
    0 q7 Y! d* l5 y9 z6 Q把里面的东西抠出来就是
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-30 16:49:41 | 显示全部楼层
    本帖最后由 wenlishahsa 于 2014-6-30 16:58 编辑
    $ T5 k- P3 H- F; Y
    4 |% G' e' h. l0 z& y  ~- B* t+ ?, m0 t>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'! Z" Z1 k4 @) t! p$ {
    >>> req = urllib2.Request(url)
    : b0 F0 s! q1 qTraceback (most recent call last):
    # H6 f: I2 A6 u$ N. A9 j* T  File "<pyshell#1>", line 1, in <module>. X4 O$ |# F/ W) p0 O
        req = urllib2.Request(url)6 R3 g, l5 R9 ~1 w5 Z6 ?- |
    NameError: name 'urllib2' is not defined>>> 楼主,请问,为什么我照你的执行会出错呢?

    点评

    出错了可以把错误拷下来直接百度  发表于 2014-6-30 17:26
    加油,你要是能把这个网站扒下来转成mdx,大家就有福了。可以先抓目录,把所有的链接抓到,然后按链接再抓网页和图片。这个网站的图片异常精美,确实让人心动,做成词典放ipad上教育小朋友很不错的。  发表于 2014-6-30 17:25
    import urllib2先  发表于 2014-6-30 17:22
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-30 18:30:34 | 显示全部楼层
    wenlishahsa 发表于 2014-6-30 16:49
    , Z! G* K5 t# R5 B) _! ?8 j>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'
    : t- `. @# O1 q, U>>> req = urllib2.Request(url ...

    / t7 r8 \1 K6 E  G, _7 D谢谢,解决了

    该用户从未签到

    发表于 2014-7-5 21:10:28 | 显示全部楼层
    感谢分享
  • TA的每日心情

    2022-1-3 20:06
  • 签到天数: 384 天

    [LV.9]以坛为家II

    发表于 2014-7-14 19:50:32 | 显示全部楼层
    我是小白。请问百度哥什么叫 “用脚本请求这个页面” 怎么做~ ~

    该用户从未签到

    发表于 2015-9-7 16:50:18 | 显示全部楼层
    版主您好,本人没有学过这些语言,也不会编写,能否下载 http://www.esdict.cn/ 一下的文件内容吗?多谢了。

    该用户从未签到

    发表于 2015-9-7 22:20:14 | 显示全部楼层
    有用的实例  经典的例解 感谢楼主 支持楼主

    该用户从未签到

    发表于 2015-10-29 13:48:35 | 显示全部楼层
    先备着,改天自己尝试一下。

    该用户从未签到

    发表于 2015-10-31 15:05:48 | 显示全部楼层
    讲的简单明了,受教了……

    该用户从未签到

    发表于 2015-12-2 17:48:15 | 显示全部楼层
    学习了,受益良多。7 r6 ~  _1 n/ t( G1 Z3 O
    狂顶楼主。。。

    该用户从未签到

    发表于 2015-12-5 22:24:37 | 显示全部楼层
    学习受教了!

    该用户从未签到

    发表于 2015-12-9 14:07:13 | 显示全部楼层
    almighty 楼主,8 C2 b' u3 f/ O/ H0 f
    可以把这个抓下来离线用吗?
  • TA的每日心情

    2023-9-27 11:08
  • 签到天数: 52 天

    [LV.5]常住居民I

    发表于 2016-1-2 12:14:03 | 显示全部楼层
    学习了,支持这种技术贴。

    该用户从未签到

    发表于 2016-1-2 12:25:09 | 显示全部楼层
    技术流!问题是能不能给给结果呢。。。。
  • TA的每日心情
    开心
    2019-6-16 20:48
  • 签到天数: 221 天

    [LV.7]常住居民III

    发表于 2016-1-2 21:29:45 | 显示全部楼层
    辛苦了 ,O(∩_∩)O谢谢

    该用户从未签到

    发表于 2016-2-2 12:02:30 | 显示全部楼层
    好帖,谢谢分享
  • TA的每日心情
    开心
    2019-6-16 20:48
  • 签到天数: 221 天

    [LV.7]常住居民III

    发表于 2016-2-17 10:31:28 | 显示全部楼层
    这个方法我得好好学习一下。
  • TA的每日心情
    无聊
    昨天 21:19
  • 签到天数: 2339 天

    [LV.Master]伴坛终老

    发表于 2016-2-20 17:53:09 | 显示全部楼层
    Python写爬虫爬...
    您需要登录后才可以回帖 登录 | 免费注册

    本版积分规则

    小黑屋|手机版|Archiver|PDAWIKI |网站地图

    GMT+8, 2025-4-27 08:26 , Processed in 0.024873 second(s), 27 queries .

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

    快速回复 返回顶部 返回列表