掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 95167|回复: 48

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

    [复制链接]

该用户从未签到

发表于 2014-6-17 19:21:42 | 显示全部楼层 |阅读模式
5 ^, p( q( W6 f$ j& m1 |
一直想找个英语单词词根和前缀、后缀的词典,主要用来辅助记单词
* f  L" T5 Z, q比如entombed,如果知道en-,知道tomb,这个单词看一遍就记住了,
# X: z7 G0 f3 o; u  O有点类似汉字的偏旁部首
0 D) G) F  s% J, b  R) ~$ r1 m找来找去,觉得prefixsuffix.com这个网站还不错,收得比较全,解释比较简明) d! F" I# i9 R3 }
但是总不能整天老挂在这网站上,得想个能离线浏览的办法6 N( x/ v) i7 \! Y
他家倒是出了个app放在appstore上,卖18元,说实话有点小贵,人家SOED6才卖18
" l& F' N% S& K  }$ B7 R" y) m  l这还不算,最要命的是从2010年以来这个app一直没更新过,究竟是不再维护了呢?还是已经完美到不用再更新了呢?
9 b( w  r  u" x0 [$ A" L要知道这几年ios都有过几次重大升级,万一买了和ios7不兼容,闪退怎么办?岂不是白买
9 X2 o0 R  r5 d! p& U5 M- w  j
" A: L8 B8 ~, K/ b0 e于是想到有没有可能把他家的数据全给扒下来4 x3 m  u1 {, A! r- \2 n
运气不错,这家网站完全没设防,扒数据的整个过程轻松而愉快& X; H, d& y! D4 X2 r  K* i1 s
现在就把这个过程详细讲讲。遇到类似问题可以照猫画虎,把附件的代码改改就能工作, Z5 k/ @/ i% z! \2 n
我尽量写得比较啰嗦一点,让计算机小白也能看懂, V! q. ]% J  V& u

* r( |3 L' a. N1 _$ h一、网页的构造  z7 u% C; \% S0 ~0 n2 \
这个网站比较简单,和词根相关的网页就两个2 e) ?. K2 k# J3 h3 q" P. h
一个是rootchart,点开是张大表,列出最常用的词根
/ j/ k" p4 J( {4 X: qhttp://www.prefixsuffix.com/rootchart.php?navblks=10110006 y: d) T& A. e9 m$ Z- l3 Q) F2 U
还有一个rootsearch,点开有个search选项,可以自己输入词根查询
2 \8 W4 F9 l3 w, Jhttp://www.prefixsuffix.com/rootsearch.php, i) R7 G9 H" v' y

& G6 D" e& t; ?/ b+ T1 |1 ]/ k7 B二、先搞第一个网页; K* @! z1 j3 p9 }
地方找到了,如何下手呢?
4 r1 J5 j. J5 C8 a第一个简单,直接用脚本请求这个页面,把返回结果接住就行
  1. / ]2 v. ]! E+ ?
  2. url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'' d4 |. b& q: Y! a7 d
  3. req = urllib2.Request(url)
    + e. w, \" |+ n2 l* @
  4. response = urllib2.urlopen(req)
    * Y' \& r5 y% y/ o- ]
  5. page = response.read()# i% _8 n; d0 X4 n
  6. print page # 打出来看看返回结果究竟是啥玩意
    9 E5 r) S. h/ A5 E. h% \
复制代码
给计算机小白扫盲
  z# b  M8 t# X% j# c1 z9 z互联网的工作原理是这样的:用户向网站发送请求,网站响应请求返回数据
2 N, T/ ?/ \9 o9 M比如用浏览器看网页这样一个最简单的操作:- s5 k9 ~0 c7 `/ Y. h3 t9 k9 |5 K
输入一个网址按回车,浏览器就向那个网站发送请求;网站返回的网页数据被浏览器接住,经过解析、渲染呈现出来8 X  o% ?6 o) t. m/ A0 V4 f
视频啥的也是一个道理,只不过这时候返回的是视频数据,不是网页数据
( \& X- s* {8 ~* H1 k这里用脚本发的请求,网站返回的数据自然也能用脚本接到
1 f, Q3 z/ O) _

5 [% W- V+ v9 @7 {0 E4 I/ m网页数据拿到了,真正需要的那一小块数据在哪呢,这个可以查一下网页的源码,右键菜单->审查元素,如下图; y1 d( H2 D) Z( m8 C7 K$ A
+ I  m( _5 E& L% P* `' e
) U/ ]9 i0 L0 D9 {! [  j) u
可以看到那块数据就在这个大表里面
  1. <table class="affix">...</table>
复制代码
在那一大篇网页数据里把这个表找到,把里面的内容给抠出来,就是一个超强的python库:BeautifulSoup的拿手好戏
& e# b# ~& q! j% n9 X9 `(这个库使用起来非常简单,文档也非常完善,有不明白的尽可以去这里查询。这里不再多说。8 S& u8 B6 a8 ^# c7 C" q
http://www.crummy.com/software/B ... 4/doc/index.zh.html% K* a  R) V5 D' h6 M/ d2 l
. n4 T& D: }8 ~% J& }
于是有下面的代码
  1. . o! M1 H0 D' \- c% o7 V& @  |6 w( t
  2. soup = BeautifulSoup(page)
    ; Z+ d/ n% Z/ {! F5 R
  3. tb = soup.find('table', {'class': 'affix'}) # 这样就把那个大表给抠出来了  H1 E! g, f, Y7 D+ b
  4. # 然后再一层一层的剥+ Y6 E$ G5 Y9 d0 V% U* A
  5. if tb:9 z# B6 u! q+ C+ Z
  6.     rows = tb.findAll('tr') # 所有行
    / G3 U; `- J5 \9 b; G
  7.     for tr in rows:* I7 |) J+ \0 Q
  8.        tds = tr.findAll('td') # 每一行的所有列8 @4 H3 `5 g& R/ d( h5 _# a9 Z: h
  9.        if tds:
    4 d: R  y/ j4 W8 k' Q9 Q% J; W/ F
  10.               。。。
    - h- g- ?/ M$ g5 p, l/ V$ E* @
复制代码
第一个网页到此解说完毕。
: s" g1 _9 S& d: ~) x7 F博客类、或者外汇牌价,基金公司的每日净值之类的公告信息,都可以用类似的办法扒数据
  I9 a$ j1 u7 D/ w4 ]" s; D& h) z
三、再搞第二个网页$ I( O! h1 n. q# O
这个稍微有点不同,它的工作原理是这样的  W6 l4 a  V- x3 d  _  n
用户输入关键字,把下拉框和"start","anywhere","end"这两项选好,点击search按钮,8 M/ D1 c  y& Y- U' n
这时候浏览器会向rootsearch.php这个页面发送请求,捎带着还要把用户刚才输入的这些数据给POST过去,
3 O8 w* X5 {# P' J& Jrootsearch.php收到这些用户数据,才知道要干啥、吐出什么东西回来
, d3 a% w% [: v1 h页面url是已经知道的,那么这里的关键问题就是:浏览器究竟把什么数据给POST过去了呢?
/ R5 K9 \! B. t1 a8 d还是要查一下网页的源码,如下图
3 g6 i$ S' \9 a+ p1 u$ T
8 P( h$ f4 W0 d. t9 ~6 c  e
( s& R$ ]# E' b( ~8 S8 R' h可以看到这是一个form,里面有这几个东西正好对应着文本框、下拉框、"start"……:
4 E3 i! B! |1 n2 l1 p1 vfield、find、stype
  g8 C7 a* ~2 ^5 k2 z* s还有个hidden的东西searching,不晓得是啥,不过没关系,它的value是固定的yes# Q2 x) U7 q/ u0 F' J+ ^# P8 y
给计算机小白扫盲
- k0 x0 R, [) Z9 k) G/ Vform叫做提交表单,用来把用户输入的数据提交到网站后台处理: \/ u; B( j3 @' s
文本框、下拉框、"start"……这些叫做网页控件# g6 H- T" q* `
注意它们的两个属性:name和value,这两个东西都是要提交给后台的,这样网站才知道用户想干嘛

3 A. n4 N. B, y  k: B: c) h
! V7 Q' B9 h4 ~- p( W* E5 O; [( h搞清楚以后,于是有下面的代码
  1. + V/ _  b  Q  N/ ?7 \1 o
  2. values = {'field': 'root', 'find': 'ex','searching': 'yes', 'stype': 'anywhere'}8 H6 o. o. x/ W# y
  3. # 这里模仿用户查询ex这个词缀,输入‘ex’
    / q7 B$ G" ]7 n* \' |2 D; T
  4. # 扒数据自然是出来的越多越好,因此把下拉框选成root,单选按钮选到anywhere, Z8 u# f/ v: D$ u& g) A
  5. # 实际上为了扒到所有的数据,我写了26个字母X26个字母的组合,anywhere/start/end各查一遍) D1 m. I6 V& T
  6. # 一共发了26X26X3次请求,比较暴力,这种丑陋的代码就不拿出来现了- H! l$ Y) l* s* O
  7. data = urllib.urlencode(values)4 |' Y. R0 L7 B! s
  8. print data # 看看变成了什么,是不是很眼熟?( J* V1 |0 u1 [0 v+ B, J7 }# T
  9. req = urllib2.Request(url, data)% M- q# b* K! x4 @: ~6 B5 w# a
  10. page = urllib2.urlopen(req)$ T4 r# Q& j& t1 u
  11. print page # 打出来看看这回又是啥玩意
    7 Y+ ?& B1 o  {9 F4 ~
复制代码
这样就又把数据搞到了,接下来的流程和上面第一个网页的BeautifulSoup那块开始往下一模一样/ \4 r, \( H8 x; f) V2 j
注:0 _" O5 r4 `' T
像这个网站这样每次检索后刷新整个页面的做法已经不多了,
" [) l) B5 l/ o6 O, Y, H- Z; j最近大量的网站使用ajax技术,网站不再返回整个html页面把整篇全部刷新6 A8 V( i% n; A3 L) v9 v: d
而是返回一小块html片段,只刷新页面的某一小块,比较环保8 l+ x5 E2 f; V; Q$ V
或者干脆只返回一大串数据,用网页的javascript解析、生成html,这种就比较头大,数据看着头晕
7 c! c9 h: w/ O# r6 k; n
7 h: w9 _$ N5 R2 l第二个网页到此解说完毕。" {1 S  F% x8 q5 Z# j0 r5 ?& u
网站登录类、论坛自动发帖类、订票类、考试报名类、抢沙发类……等等原理上都是这样实现的
9 [! t& P1 G/ ~6 ?, K+ T4 l! [! O% U, e+ D) h0 F
5 K. V8 G8 c4 u: k5 }# ~
看到这里你应该想明白了,为什么现在各个网站都要限制连接间隔、用图片验证码
5 X& P8 k! U, F/ ?/ [9 d还有用短信发验证码的,有些还搞了数据加密、随机数什么的。。。不这么搞网站服务器就要沦陷了
9 }0 q# Y) p% k% B# D/ X所以上面的代码通常会遇到网站的各种阻挠,让你抓不到数据,需要你和网站斗智斗勇
& i- t) j3 R& S: X( L+ }9 c" U像图片验证码这玩意最近已经都不太好使了,有人收集大量的验证码图片建特征数据库,一样能突破网站的防线
  m( y/ E, v2 Z; v于是最近很多网站的图片验证码搞得极其扭曲,以至于本人用肉眼看半天都输错,+ t/ ]! u4 t7 i2 I4 a
已经到了人类都无法识别的地步。这种网站估计是留着给外星人用的。4 G0 i% t( W- v, g# O

7 X0 ~3 w9 ^5 c: g* C9 h: V$ K: }

本帖子中包含更多资源

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

x

评分

2

查看全部评分

本帖被以下淘专辑推荐:

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

    [LV.1]初来乍到

    发表于 2018-7-28 13:22:31 | 显示全部楼层
    首先,非常感謝樓主。1 @9 W. o/ K: R" w
    我獲得affix2.txt后,分別用MdxBuilder3.0、4.0X32、x64創建mdx,4.0版都沒問題,但3.0版總是創建失敗,; {1 z; P7 ~' t
    Done!. i4 t6 @6 T% t* u* l
    Original index size = 0KB, compressed size = 0KB, compression ratio = 314%
    , {& O" _$ ~4 O6 z2 ^1 kTime used for this section: 0 seconds
    5 K& |4 B( b- w" T, ]' O5 QBegin processing data contents...
    7 L- x  ^% b3 M5 t$ }Failed to read from source file:C:\Users\frankly\Desktop\affix2.txt for record(line):1% i$ a6 ^2 b8 Z* X3 ^/ h. [- i
    Conversion failed!
    # J% {; W- j4 W' h! K  @+ A. O請各位指教,謝謝。
  • TA的每日心情
    擦汗
    2022-3-12 13:24
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2016-10-12 16:46:54 | 显示全部楼层
    bt4baidu 发表于 2014-6-29 23:27
    1 o/ |* B( W7 d0 \+ T: d这种静态网页按我上面的说明毫无压力吧
    / O& C) i# O/ I7 n" H2 B比如http://www.nsii.org.cn/node/80/A/Acanthus/Acanthus%20leu ...
    * z1 @' U, k; S  q5 C6 c. h  M) v/ ]
    楼主问一下您的 wish list 上的 英语电子词典都找到了吗?, D) z( ~7 }, I
    辛苦了% ?% D7 ~; E9 Z; p0 f" d
    如果找到了能不能也给我分享一下? 邮箱[email protected]
    * q# q( ~, x& X) g6 l\thanks\a\lot\  :0 4 e: H* T# Q6 k9 q$ n1 D3 P
    :)

    该用户从未签到

    发表于 2016-5-16 18:10:45 | 显示全部楼层
    楼主发出来的代码好整洁! 学习耶- C+ ^1 k- }: F3 S; C; `% M
    ) b( b! W$ }/ 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 | 显示全部楼层
    好贴要顶!
    0 j1 Q9 S, E9 q- o. t7 n7 q7 ]
  • TA的每日心情
    开心
    14 小时前
  • 签到天数: 2577 天

    [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 6 T, e9 g! t) ]: P
    楼主,请帮忙,这个网站的如何扒http://www.nsii.org.cn/newquery?qs=*:*&fq=kingdom:Plantae ?
    # r- h2 n3 b1 U+ ~5 k+ T9 a
    这种静态网页按我上面的说明毫无压力吧
    5 }, |) U* U+ H比如http://www.nsii.org.cn/node/80/A ... hus%20leucostachyus% T4 J: G' O" C* o( v4 [
    这个页面,找到
    % }) G6 o  q# }) Z- O* s<div class="content clearfix">
    : _. X# u, M! l! a) c- n% M...
    4 Y5 n$ H6 t4 \$ j$ a0 A* K</div>
    " z6 Y- y2 O5 s, S( F* C把里面的东西抠出来就是
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-30 16:49:41 | 显示全部楼层
    本帖最后由 wenlishahsa 于 2014-6-30 16:58 编辑
    7 n+ v" b9 a3 {& G) y# G6 R2 u
    5 B9 U7 a" z; k! [' {5 R8 L3 F. d>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'4 N" r6 W9 R6 d" q4 h+ f
    >>> req = urllib2.Request(url)3 k" I5 v; j7 w+ c/ p9 u
    Traceback (most recent call last):
    : k! z9 _( L5 O0 A6 a; e  File "<pyshell#1>", line 1, in <module>% e( B1 z3 t& Q) D8 k8 q' c
        req = urllib2.Request(url)2 r5 W3 \( [& B7 N8 N
    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
      [5 C% C. _: o4 u>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'
    ( ^: g2 I. {2 O* }1 m+ i( ?>>> req = urllib2.Request(url ...

    ! I0 S$ W( W/ h' f+ D5 C6 U4 t5 l谢谢,解决了

    该用户从未签到

    发表于 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 | 显示全部楼层
    学习了,受益良多。* p$ V8 {* p0 g) o  f' a1 [' d
    狂顶楼主。。。

    该用户从未签到

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

    该用户从未签到

    发表于 2015-12-9 14:07:13 | 显示全部楼层
    almighty 楼主,1 \/ G7 l9 d: f4 e3 H! u) g: s
    可以把这个抓下来离线用吗?
  • 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:14
  • 签到天数: 2346 天

    [LV.Master]伴坛终老

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

    本版积分规则

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

    GMT+8, 2025-5-4 19:38 , Processed in 0.026483 second(s), 27 queries .

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

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