掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 98240|回复: 48

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

    [复制链接]

该用户从未签到

发表于 2014-6-17 19:21:42 | 显示全部楼层 |阅读模式
7 ~% R. ?( t6 _, c( ]1 Z8 I
一直想找个英语单词词根和前缀、后缀的词典,主要用来辅助记单词
7 v! ]( d% L8 G* ~: H0 ^比如entombed,如果知道en-,知道tomb,这个单词看一遍就记住了,
0 ~/ O; E* @! V. F2 {有点类似汉字的偏旁部首
: S& S- s( V' i' c5 M" Q9 t4 X找来找去,觉得prefixsuffix.com这个网站还不错,收得比较全,解释比较简明
/ x0 ~* p7 i. n7 y/ l但是总不能整天老挂在这网站上,得想个能离线浏览的办法
& @0 `7 `6 _3 e$ M& ]7 ^他家倒是出了个app放在appstore上,卖18元,说实话有点小贵,人家SOED6才卖18. g! _  u! y$ ^
这还不算,最要命的是从2010年以来这个app一直没更新过,究竟是不再维护了呢?还是已经完美到不用再更新了呢?3 n# _8 j1 y) T
要知道这几年ios都有过几次重大升级,万一买了和ios7不兼容,闪退怎么办?岂不是白买* [8 N0 o! Z% X7 `
0 J: P- `5 \; F$ n8 r
于是想到有没有可能把他家的数据全给扒下来
" t' k2 U5 F: I5 L' K$ F5 h运气不错,这家网站完全没设防,扒数据的整个过程轻松而愉快
$ Y$ Z3 }/ |- W+ }现在就把这个过程详细讲讲。遇到类似问题可以照猫画虎,把附件的代码改改就能工作- N: A. z+ E1 c  q, r* @: J
我尽量写得比较啰嗦一点,让计算机小白也能看懂1 C( O. e$ S6 {% i3 t9 p+ F# L' n

) o4 D7 U) G" N4 P/ g* K一、网页的构造
. G. o4 E$ f0 T- ^这个网站比较简单,和词根相关的网页就两个$ V+ t' P1 e0 N: I6 M/ M
一个是rootchart,点开是张大表,列出最常用的词根
- i) U' g( _- t4 {! zhttp://www.prefixsuffix.com/rootchart.php?navblks=1011000( v9 f% J' c& c
还有一个rootsearch,点开有个search选项,可以自己输入词根查询9 w, p) U2 ?% B% w
http://www.prefixsuffix.com/rootsearch.php
8 p& D. E, o$ x+ H; |3 Z- Z" B) l* v! h: f' T. \$ L, m
二、先搞第一个网页; N6 r. X. g& Q* h6 K2 u5 P; f
地方找到了,如何下手呢?
6 V. ]& u: Q. Z6 }' A, C0 \第一个简单,直接用脚本请求这个页面,把返回结果接住就行

  1. 1 V/ U& X/ z; D- U7 w
  2. url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'' W4 \& f" c( B7 b: x
  3. req = urllib2.Request(url)* _" e$ i0 H5 _6 E3 X7 ]/ |
  4. response = urllib2.urlopen(req)
    4 [; U% p7 M. i; {
  5. page = response.read()
    6 Z& U+ M: {3 S, }" J
  6. print page # 打出来看看返回结果究竟是啥玩意: {( \; z6 p0 y6 g
复制代码
给计算机小白扫盲
: I  D" Q7 B8 o互联网的工作原理是这样的:用户向网站发送请求,网站响应请求返回数据
) Q/ F+ \) C+ o( }$ O  K比如用浏览器看网页这样一个最简单的操作:; O& v1 K+ v2 _. `
输入一个网址按回车,浏览器就向那个网站发送请求;网站返回的网页数据被浏览器接住,经过解析、渲染呈现出来  E  J  I3 Q' H$ W: Z
视频啥的也是一个道理,只不过这时候返回的是视频数据,不是网页数据6 U$ i* Z& Y8 C4 K2 r
这里用脚本发的请求,网站返回的数据自然也能用脚本接到
4 K+ O' D2 a* y1 f

6 [! z$ S$ m2 X& j! x网页数据拿到了,真正需要的那一小块数据在哪呢,这个可以查一下网页的源码,右键菜单->审查元素,如下图, a8 e2 Q; n0 n
# v$ U$ H1 @( e' M! O1 n0 k

0 A. {; w2 ~3 X$ N, E) W2 g0 }8 z可以看到那块数据就在这个大表里面
  1. <table class="affix">...</table>
复制代码
在那一大篇网页数据里把这个表找到,把里面的内容给抠出来,就是一个超强的python库:BeautifulSoup的拿手好戏
8 [( m5 P4 y2 o7 ]! H(这个库使用起来非常简单,文档也非常完善,有不明白的尽可以去这里查询。这里不再多说。
& J: g: \$ y8 j- ehttp://www.crummy.com/software/B ... 4/doc/index.zh.html3 L) r" D# h( `- r& H( P

. v0 Q3 g! H+ p1 X于是有下面的代码

  1. * d4 N( c/ w2 \7 c6 @
  2. soup = BeautifulSoup(page)' y; t0 U, W* a9 F) K1 b/ L
  3. tb = soup.find('table', {'class': 'affix'}) # 这样就把那个大表给抠出来了6 O8 N) b7 {' N+ \, B9 l/ O- h
  4. # 然后再一层一层的剥7 o! V+ ~$ R# O" ~1 n; r* {
  5. if tb:( l- a1 Q; M) i
  6.     rows = tb.findAll('tr') # 所有行
    9 n3 C  C; P* t& `: F( I5 S) n+ x
  7.     for tr in rows:5 O# P% k" `* N# P. [, _. t
  8.        tds = tr.findAll('td') # 每一行的所有列
    * K% v1 R5 b: J' Q2 x  p
  9.        if tds:& d8 c. z$ v' ?' {2 B: |
  10.               。。。7 H5 s  I0 j# T! V; v
复制代码
第一个网页到此解说完毕。
* E; D/ [" f3 p4 }' V) P4 h$ P. D2 s博客类、或者外汇牌价,基金公司的每日净值之类的公告信息,都可以用类似的办法扒数据7 m: I" S# h6 q. c* u( F; x

2 B3 J1 X' W4 P1 v7 J三、再搞第二个网页$ Z' r* y8 G* Y; ^2 D& x: o' ?. B
这个稍微有点不同,它的工作原理是这样的) b& Q! J% e: ?9 `9 Y3 t6 ]5 K+ R3 j3 o
用户输入关键字,把下拉框和"start","anywhere","end"这两项选好,点击search按钮,5 E$ d" e% Y! {5 G; ^
这时候浏览器会向rootsearch.php这个页面发送请求,捎带着还要把用户刚才输入的这些数据给POST过去,! E7 Z; O3 i% y; {3 H! `- {
rootsearch.php收到这些用户数据,才知道要干啥、吐出什么东西回来: O) Z; v$ D2 ^
页面url是已经知道的,那么这里的关键问题就是:浏览器究竟把什么数据给POST过去了呢?
6 y& \0 F/ U9 K( Q- b' J9 `还是要查一下网页的源码,如下图) w. l4 a4 x/ g# `# _

9 Y# A! z( B' X% j1 {
0 Q' i  L0 j- i/ Z可以看到这是一个form,里面有这几个东西正好对应着文本框、下拉框、"start"……:
1 I9 D8 t9 J. `9 ~9 c% K# x% S0 gfield、find、stype
3 U$ f( s1 u# ]; N$ r6 l还有个hidden的东西searching,不晓得是啥,不过没关系,它的value是固定的yes& a4 ]) w1 S5 V' M5 ^
给计算机小白扫盲
. S  t. K1 F' k) m) q3 z) {form叫做提交表单,用来把用户输入的数据提交到网站后台处理
1 U' r5 p8 x# {( s" A文本框、下拉框、"start"……这些叫做网页控件
, `& x% X/ O! _2 ]1 I  M. U: |+ M注意它们的两个属性:name和value,这两个东西都是要提交给后台的,这样网站才知道用户想干嘛

; r" m9 I$ D; i( |' t+ P: C5 R
) b; W* T9 P4 c搞清楚以后,于是有下面的代码
  1. 3 P) D. t- o* Y+ ]. T
  2. values = {'field': 'root', 'find': 'ex','searching': 'yes', 'stype': 'anywhere'}
    $ a# @7 B& ]$ ?& }) Q8 N
  3. # 这里模仿用户查询ex这个词缀,输入‘ex’
      Z& u/ T9 ^' P6 J
  4. # 扒数据自然是出来的越多越好,因此把下拉框选成root,单选按钮选到anywhere
    9 x5 R) c7 b+ B
  5. # 实际上为了扒到所有的数据,我写了26个字母X26个字母的组合,anywhere/start/end各查一遍& |' B" s2 @: s* K3 S5 ^3 Y5 q. C
  6. # 一共发了26X26X3次请求,比较暴力,这种丑陋的代码就不拿出来现了& R7 u9 S9 b+ B" \' e
  7. data = urllib.urlencode(values)/ r2 \: W) \3 U5 {3 }$ s6 g: z
  8. print data # 看看变成了什么,是不是很眼熟?
    " v9 [. z( g' n% Q6 {
  9. req = urllib2.Request(url, data), I# ~5 v" d1 e: y: u+ }
  10. page = urllib2.urlopen(req)8 v. i5 g; M" k. x" d' p1 @! C
  11. print page # 打出来看看这回又是啥玩意8 M$ M. n) o, m' A$ g' ]
复制代码
这样就又把数据搞到了,接下来的流程和上面第一个网页的BeautifulSoup那块开始往下一模一样, x5 ^7 D+ q1 d2 `  C1 d" U
注:" U. C. B' N; |) L/ u: W2 k
像这个网站这样每次检索后刷新整个页面的做法已经不多了,
; Z% d( t8 P; |& b' n8 d: N最近大量的网站使用ajax技术,网站不再返回整个html页面把整篇全部刷新
: M6 }  `+ D: M( H% o3 }而是返回一小块html片段,只刷新页面的某一小块,比较环保
- l& a1 v1 W, [  c. d/ r% D  q或者干脆只返回一大串数据,用网页的javascript解析、生成html,这种就比较头大,数据看着头晕' P5 ^. g0 \( a. e
! x; p1 e1 Q5 g$ M  Y; v
第二个网页到此解说完毕。
# p' y* ?; u1 f: n; }+ X网站登录类、论坛自动发帖类、订票类、考试报名类、抢沙发类……等等原理上都是这样实现的/ Y1 t9 L* q3 s

# R& I7 j+ |0 J0 W
) Z" u4 |9 _% i看到这里你应该想明白了,为什么现在各个网站都要限制连接间隔、用图片验证码2 h9 k/ r# V" T% C% O
还有用短信发验证码的,有些还搞了数据加密、随机数什么的。。。不这么搞网站服务器就要沦陷了
8 N( p- z: j0 r( Z9 @( ?: h, g& ]所以上面的代码通常会遇到网站的各种阻挠,让你抓不到数据,需要你和网站斗智斗勇% c6 [; v/ O3 z/ v/ v* j
像图片验证码这玩意最近已经都不太好使了,有人收集大量的验证码图片建特征数据库,一样能突破网站的防线
* T3 W2 x0 [4 H) i$ C: ?+ B于是最近很多网站的图片验证码搞得极其扭曲,以至于本人用肉眼看半天都输错,
7 Y! I. L# H2 q3 I" s& r8 P- ]已经到了人类都无法识别的地步。这种网站估计是留着给外星人用的。
) U# V9 J) i6 x- P* i8 r
  M% @7 v2 ^4 E/ P; T0 z

本帖子中包含更多资源

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

x

评分

2

查看全部评分

本帖被以下淘专辑推荐:

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

    [LV.1]初来乍到

    发表于 2018-7-28 13:22:31 | 显示全部楼层
    首先,非常感謝樓主。
    7 E+ C/ R' ]% l7 [; C8 a- A/ l( D我獲得affix2.txt后,分別用MdxBuilder3.0、4.0X32、x64創建mdx,4.0版都沒問題,但3.0版總是創建失敗,
    0 H1 I( {' ?% K: [% h7 r$ y  U+ TDone!+ l' {- R( \9 l" i/ C
    Original index size = 0KB, compressed size = 0KB, compression ratio = 314%
    & U  N% M1 I. k: l8 n2 zTime used for this section: 0 seconds
    6 b3 _# V& `8 B0 b3 KBegin processing data contents...
    ! E6 g5 [; G# ~0 `9 F0 r6 i, V9 d# ZFailed to read from source file:C:\Users\frankly\Desktop\affix2.txt for record(line):1+ j  K+ M* O9 F
    Conversion failed!5 N# g* j- R7 J8 @7 B. g6 F$ d/ C
    請各位指教,謝謝。
  • TA的每日心情
    擦汗
    2022-3-12 13:24
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2016-10-12 16:46:54 | 显示全部楼层
    bt4baidu 发表于 2014-6-29 23:27
    3 m3 A$ S8 j( j4 a+ V6 \这种静态网页按我上面的说明毫无压力吧
      c. x& k& i: g1 v$ C7 a" b) s; \, d比如http://www.nsii.org.cn/node/80/A/Acanthus/Acanthus%20leu ...
    ' v$ o; o8 D+ H- E
    楼主问一下您的 wish list 上的 英语电子词典都找到了吗?
    1 b1 B6 o2 ~  A+ B6 I5 a辛苦了
    3 Q6 u* j& n% @如果找到了能不能也给我分享一下? 邮箱[email protected]
    8 ?) F! O( t) {+ [) g! g  v\thanks\a\lot\  :0 ) |# V6 N$ ]. a' s# G8 `
    :)

    该用户从未签到

    发表于 2016-5-16 18:10:45 | 显示全部楼层
    楼主发出来的代码好整洁! 学习耶
    2 N3 V2 z$ R5 o( n0 _$ w1 O$ p5 |* b2 R0 V
    请教一下 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 | 显示全部楼层
    好贴要顶!0 x- W1 ]& [& Z5 z5 [# K- H, h
  • TA的每日心情
    开心
    2026-5-17 05:44
  • 签到天数: 2908 天

    [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
    8 i, T; o  y, l+ s9 E# J2 p8 r楼主,请帮忙,这个网站的如何扒http://www.nsii.org.cn/newquery?qs=*:*&fq=kingdom:Plantae ?
    9 H! }. P- f. Q
    这种静态网页按我上面的说明毫无压力吧
    ! J" ^4 g- B4 ~, x+ L比如http://www.nsii.org.cn/node/80/A ... hus%20leucostachyus
    & a1 s$ h4 f7 a0 I0 _: ^3 q这个页面,找到
    5 \9 Y1 Z/ V" z/ d& G2 x& }<div class="content clearfix">% s2 p$ m2 H! g+ s5 n: z
    ...
    ( h, v4 C* E. g! b2 w: T</div>; y: N1 S& n0 [0 `) \3 N* m
    把里面的东西抠出来就是
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-30 16:49:41 | 显示全部楼层
    本帖最后由 wenlishahsa 于 2014-6-30 16:58 编辑 ) j) i( O) o* r4 E  r0 B% I

    % h6 H: ^5 ~- i5 r$ D# t>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'
    . g% ^. E5 {* q! H1 o( H3 p: n>>> req = urllib2.Request(url)+ f% ^) E$ G1 l
    Traceback (most recent call last):
    4 a; r8 b4 S  K  File "<pyshell#1>", line 1, in <module>
    * R" _; c# z! [1 h8 a    req = urllib2.Request(url)' w/ k2 [( u; [( ]9 e: l
    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
    ) l$ P+ I+ \; j+ o2 Y, }) T>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'8 O3 k+ ?3 a" h: o8 z
    >>> req = urllib2.Request(url ...

    0 W$ o- f( u% w7 W2 S" P谢谢,解决了

    该用户从未签到

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

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

    [LV.9]以坛为家II

    发表于 2014-7-14 19:50:32 | 显示全部楼层
    我是小白。请问百度哥什么叫 “用脚本请求这个页面” 怎么做~ ~
  • TA的每日心情
    开心
    2026-1-23 23:15
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 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 | 显示全部楼层
    学习了,受益良多。2 P  X3 [& y: m0 X2 i7 B
    狂顶楼主。。。

    该用户从未签到

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

    该用户从未签到

    发表于 2015-12-9 14:07:13 | 显示全部楼层
    almighty 楼主,' x2 w0 s/ \) I, `. N: }3 u
    可以把这个抓下来离线用吗?
  • 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的每日心情
    无聊
    昨天 23:55
  • 签到天数: 2821 天

    [LV.Master]伴坛终老

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

    本版积分规则

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

    GMT+8, 2026-8-31 06:53 , Processed in 0.046230 second(s), 33 queries .

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

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