掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 93813|回复: 48

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

    [复制链接]

该用户从未签到

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

  K4 ^1 L; b7 \; g一直想找个英语单词词根和前缀、后缀的词典,主要用来辅助记单词( ^- |9 h& ]& _1 ~
比如entombed,如果知道en-,知道tomb,这个单词看一遍就记住了,
: h$ Z4 j8 \& E$ Q有点类似汉字的偏旁部首
' ~) }  I: f! S+ c; [找来找去,觉得prefixsuffix.com这个网站还不错,收得比较全,解释比较简明: j- X& u/ h/ W' B8 [, P+ l9 D6 w
但是总不能整天老挂在这网站上,得想个能离线浏览的办法
+ H% z% A# t9 U/ ]/ J他家倒是出了个app放在appstore上,卖18元,说实话有点小贵,人家SOED6才卖18
' R2 L  t% a/ x2 H这还不算,最要命的是从2010年以来这个app一直没更新过,究竟是不再维护了呢?还是已经完美到不用再更新了呢?
8 {: g/ l* V2 U要知道这几年ios都有过几次重大升级,万一买了和ios7不兼容,闪退怎么办?岂不是白买
2 o1 c- ?% ?1 N( J, r; y0 w& ?# U6 X, v7 I) V
于是想到有没有可能把他家的数据全给扒下来
1 o; \4 U& h6 s/ r5 r+ R; t( D运气不错,这家网站完全没设防,扒数据的整个过程轻松而愉快
- ^2 a  E. m4 _, K( m0 k8 N现在就把这个过程详细讲讲。遇到类似问题可以照猫画虎,把附件的代码改改就能工作
& H' s1 i7 h7 y: K$ z8 M& c7 h我尽量写得比较啰嗦一点,让计算机小白也能看懂# Q4 }0 z6 p! i  r

- H+ l1 J) i) h. P& d' w7 i一、网页的构造4 J* D! R/ w: v! y: F3 {, M
这个网站比较简单,和词根相关的网页就两个
2 ]! u* E5 R# c# }9 E一个是rootchart,点开是张大表,列出最常用的词根, N( T" \% Z, W; ~# @
http://www.prefixsuffix.com/rootchart.php?navblks=1011000
, k# E0 U7 M$ T0 I$ U还有一个rootsearch,点开有个search选项,可以自己输入词根查询
% r+ ~' I2 Q* u* k  }' N- l( Fhttp://www.prefixsuffix.com/rootsearch.php
7 ~3 _1 a7 }' x1 T3 f/ P, d
8 |+ ~4 I$ A& b8 N6 H; k. K8 b二、先搞第一个网页1 a- q0 q: Y0 J6 Q1 S/ v, l% L+ J8 b
地方找到了,如何下手呢?4 y" M2 W& L7 |; F
第一个简单,直接用脚本请求这个页面,把返回结果接住就行

  1. 7 s+ K+ U# R3 k3 Q% [9 f
  2. url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'
    3 g9 e* W; d$ g0 @: ]
  3. req = urllib2.Request(url)
    # P4 A& {* R; v
  4. response = urllib2.urlopen(req)% @3 ~- R2 M# x" \8 u& U$ D
  5. page = response.read()
    ) }2 _& R" m: ?, j' _# S" L
  6. print page # 打出来看看返回结果究竟是啥玩意! P5 N# G8 C1 O) A
复制代码
给计算机小白扫盲
! [$ c% E+ @$ V! j互联网的工作原理是这样的:用户向网站发送请求,网站响应请求返回数据
# H# `+ S. p& ^8 _7 _7 ^; A7 e比如用浏览器看网页这样一个最简单的操作:; I/ ^: G% ~6 I' G; D+ L" w9 j; M4 n2 C# j
输入一个网址按回车,浏览器就向那个网站发送请求;网站返回的网页数据被浏览器接住,经过解析、渲染呈现出来1 U* Z9 Z0 O4 h# e+ i
视频啥的也是一个道理,只不过这时候返回的是视频数据,不是网页数据
5 t0 n5 L! ^- e+ c: f& F& |- `* l这里用脚本发的请求,网站返回的数据自然也能用脚本接到
( a0 b+ S/ D0 }! b5 t8 z  Q& s9 s. k
# |. f$ E6 [$ S! n& _
网页数据拿到了,真正需要的那一小块数据在哪呢,这个可以查一下网页的源码,右键菜单->审查元素,如下图: A) A3 y% e1 `) m% q% u

6 x9 Q9 p$ @- m9 e; X4 y) u4 u$ \4 M5 A& A# z" [& _$ L
可以看到那块数据就在这个大表里面
  1. <table class="affix">...</table>
复制代码
在那一大篇网页数据里把这个表找到,把里面的内容给抠出来,就是一个超强的python库:BeautifulSoup的拿手好戏
# ]- x/ l' Y- `- C3 C(这个库使用起来非常简单,文档也非常完善,有不明白的尽可以去这里查询。这里不再多说。
  `! z( n0 J' l( Y% ^0 j& ghttp://www.crummy.com/software/B ... 4/doc/index.zh.html( m( ~) n" n# w! n+ ^* z9 }

7 c* c' G. A( U9 m于是有下面的代码

  1. ; H0 m0 P& D2 a% w4 d
  2. soup = BeautifulSoup(page)$ x5 X+ g) D& f5 N. J$ H7 b7 u4 ^6 ^( C0 ^
  3. tb = soup.find('table', {'class': 'affix'}) # 这样就把那个大表给抠出来了
    8 l- @; T7 R8 G8 H& b7 F) |
  4. # 然后再一层一层的剥
    6 w# d( h1 k! y8 |7 N4 A6 k
  5. if tb:
    ' @( p3 u* n8 @; l+ t
  6.     rows = tb.findAll('tr') # 所有行: [7 y: ?* Q3 ], ?& O' ^
  7.     for tr in rows:
    & B+ ~3 y( z9 N6 {( n# _1 y. ]* Q
  8.        tds = tr.findAll('td') # 每一行的所有列
    9 f. h3 b. W0 J- D+ R
  9.        if tds:
    * Q% ~- Y# B8 y
  10.               。。。
    / a! X; h9 R& Z/ T( Y' y
复制代码
第一个网页到此解说完毕。
3 ^- J" c; r" ~4 b+ A  G' T9 V博客类、或者外汇牌价,基金公司的每日净值之类的公告信息,都可以用类似的办法扒数据, F+ w# F0 L( Q! d0 H6 s) h0 h
2 j% \, g) c! r8 I7 w) y' C  r
三、再搞第二个网页
9 m( H. \4 t6 ~# h9 z7 U这个稍微有点不同,它的工作原理是这样的
( ^( _8 H  X9 {* N& l- P) `用户输入关键字,把下拉框和"start","anywhere","end"这两项选好,点击search按钮,
4 B6 n: S4 _3 v, k- T9 c, X) p1 b这时候浏览器会向rootsearch.php这个页面发送请求,捎带着还要把用户刚才输入的这些数据给POST过去,0 {9 \* s  `% e& I
rootsearch.php收到这些用户数据,才知道要干啥、吐出什么东西回来
7 `. V! C% M  J页面url是已经知道的,那么这里的关键问题就是:浏览器究竟把什么数据给POST过去了呢?: o; N! R: E% Z( I6 U$ \
还是要查一下网页的源码,如下图5 i5 D8 |  x4 K& a
* Q/ j- X0 L  t& a4 Q, N

+ C" c5 y3 J- ^可以看到这是一个form,里面有这几个东西正好对应着文本框、下拉框、"start"……:
7 k5 Z. t' m8 Q/ u9 t( yfield、find、stype4 v# M) }; j7 d- F* p
还有个hidden的东西searching,不晓得是啥,不过没关系,它的value是固定的yes% c. e0 A! \$ h9 z3 Q6 i% C
给计算机小白扫盲
) z. E+ t% Y$ R" F" B( }, Gform叫做提交表单,用来把用户输入的数据提交到网站后台处理! m- ?8 i: p: w
文本框、下拉框、"start"……这些叫做网页控件
# H- o) P0 }7 p/ i- O8 M  z5 d注意它们的两个属性:name和value,这两个东西都是要提交给后台的,这样网站才知道用户想干嘛

# u* E" a. A0 B6 S' _+ C- Y3 P4 S3 k- w2 P4 Z; }7 N
搞清楚以后,于是有下面的代码
  1. + f: D  Q, A2 C) @) W9 i! R. w
  2. values = {'field': 'root', 'find': 'ex','searching': 'yes', 'stype': 'anywhere'}
    $ Y7 b+ t- A1 _9 L/ h" u1 F
  3. # 这里模仿用户查询ex这个词缀,输入‘ex’) y; a) X( V: |: D) a
  4. # 扒数据自然是出来的越多越好,因此把下拉框选成root,单选按钮选到anywhere( i5 Q) Z2 ?* ]; h# `, e" @
  5. # 实际上为了扒到所有的数据,我写了26个字母X26个字母的组合,anywhere/start/end各查一遍
    1 }& H# J! R$ q
  6. # 一共发了26X26X3次请求,比较暴力,这种丑陋的代码就不拿出来现了2 i$ S' n8 T, G7 o9 ~3 I
  7. data = urllib.urlencode(values)
    " z9 [$ M$ z; c6 G& C1 t% w# H3 P
  8. print data # 看看变成了什么,是不是很眼熟?
    8 T8 a) N, l: Q0 p5 H" p7 b5 Q8 R
  9. req = urllib2.Request(url, data)4 \" L& }" C% c8 J( M' H; |6 R0 B- p
  10. page = urllib2.urlopen(req)
    * ~$ }1 ]7 c5 F4 X( A9 Q+ z
  11. print page # 打出来看看这回又是啥玩意) ?! K& D/ C5 \+ @0 f# p
复制代码
这样就又把数据搞到了,接下来的流程和上面第一个网页的BeautifulSoup那块开始往下一模一样
4 w) c0 y4 q0 {注:
0 r! w' f$ n: t3 y像这个网站这样每次检索后刷新整个页面的做法已经不多了,& Y! c! q' N6 `( X( s2 g2 _
最近大量的网站使用ajax技术,网站不再返回整个html页面把整篇全部刷新
8 I% S$ m8 e; Z& N# ^! p而是返回一小块html片段,只刷新页面的某一小块,比较环保
+ N) i6 [# t( w或者干脆只返回一大串数据,用网页的javascript解析、生成html,这种就比较头大,数据看着头晕3 J8 Q6 B. j7 Q# B: P* y

! y1 `# |; k) ^第二个网页到此解说完毕。
/ Q7 W* Y* O( Q0 G) |" O/ V+ ^网站登录类、论坛自动发帖类、订票类、考试报名类、抢沙发类……等等原理上都是这样实现的
. o/ d% r: S. a, R" b% S) L, {2 B% H* J4 _" j' M% l  k$ W' Y* A
/ }' M3 C* [6 G
看到这里你应该想明白了,为什么现在各个网站都要限制连接间隔、用图片验证码4 Y' R2 [. O' p- `) _
还有用短信发验证码的,有些还搞了数据加密、随机数什么的。。。不这么搞网站服务器就要沦陷了
4 N: j- X6 t( {& G, \+ A. R所以上面的代码通常会遇到网站的各种阻挠,让你抓不到数据,需要你和网站斗智斗勇
% N' c( `7 o" q3 `0 }像图片验证码这玩意最近已经都不太好使了,有人收集大量的验证码图片建特征数据库,一样能突破网站的防线
  H, u" j+ a/ ?/ T) u" r1 q+ t1 k于是最近很多网站的图片验证码搞得极其扭曲,以至于本人用肉眼看半天都输错,; R5 T' E4 n% j  R* P) d( o: j
已经到了人类都无法识别的地步。这种网站估计是留着给外星人用的。. Z) ~$ G% `( T9 }$ Q8 [
  Q$ A" m) ^4 t9 [, l

本帖子中包含更多资源

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

x

评分

2

查看全部评分

本帖被以下淘专辑推荐:

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

    [LV.1]初来乍到

    发表于 2018-7-28 13:22:31 | 显示全部楼层
    首先,非常感謝樓主。( p; ?5 M1 f' T4 G0 v; j4 [
    我獲得affix2.txt后,分別用MdxBuilder3.0、4.0X32、x64創建mdx,4.0版都沒問題,但3.0版總是創建失敗,
    , k3 g& G  b0 A! \- R( }Done!
    $ [$ x; {) Z+ I5 s" |0 [4 g) xOriginal index size = 0KB, compressed size = 0KB, compression ratio = 314%
    . J5 x0 A  f6 D. X% g$ e! OTime used for this section: 0 seconds) a4 n; I4 i; F
    Begin processing data contents...: ?4 @+ x0 G; m7 M& f
    Failed to read from source file:C:\Users\frankly\Desktop\affix2.txt for record(line):16 H% t# k' j, g5 a$ C0 R4 A
    Conversion failed!! f# J- L0 x  |: T) L8 O4 s8 {
    請各位指教,謝謝。
  • TA的每日心情
    擦汗
    2022-3-12 13:24
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2016-10-12 16:46:54 | 显示全部楼层
    bt4baidu 发表于 2014-6-29 23:276 v. D+ V" V* u* e+ ~
    这种静态网页按我上面的说明毫无压力吧9 a2 G  R6 a/ R% F- t
    比如http://www.nsii.org.cn/node/80/A/Acanthus/Acanthus%20leu ...

    , V! C( {! V, O5 L! x楼主问一下您的 wish list 上的 英语电子词典都找到了吗?
    ; _9 |& t( Y* H6 @4 L- W辛苦了
    5 d& w& D! u# H% A* S! U如果找到了能不能也给我分享一下? 邮箱[email protected] 1 E* C/ T( a3 ?. A" e; E3 z& k
    \thanks\a\lot\  :0
    1 L  Y- M: M3 m:)

    该用户从未签到

    发表于 2016-5-16 18:10:45 | 显示全部楼层
    楼主发出来的代码好整洁! 学习耶/ j3 u& ^7 v  V5 w
    4 v* D6 m5 e3 h. Z- T2 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 | 显示全部楼层
    好贴要顶!
    % d) E) x6 @: F- Y) `) a
  • TA的每日心情
    开心
    8 小时前
  • 签到天数: 2244 天

    [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 ) Y! [% f1 [, t  l2 A& t
    楼主,请帮忙,这个网站的如何扒http://www.nsii.org.cn/newquery?qs=*:*&fq=kingdom:Plantae ?
    & |) [4 {- A4 E& f: J
    这种静态网页按我上面的说明毫无压力吧+ ?7 x. ?) G1 D: U$ s* G" J
    比如http://www.nsii.org.cn/node/80/A ... hus%20leucostachyus  t+ y- ]' w: F$ L# r. O
    这个页面,找到  M' V% {0 ?5 j) @8 T
    <div class="content clearfix">
    # ^1 {0 \- U" s) v. W8 I( T...
      G+ ?# y) b/ x</div>7 k4 k, t# g, m$ a! L
    把里面的东西抠出来就是
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-30 16:49:41 | 显示全部楼层
    本帖最后由 wenlishahsa 于 2014-6-30 16:58 编辑 & j4 [; A  c& C0 t
    , B3 r* r, e+ a/ K% a1 v
    >>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000') t- Z. h. S* k& w- s1 H. _6 H
    >>> req = urllib2.Request(url)
    ' m! x( D: v3 b9 S6 @- iTraceback (most recent call last):
    " Y  h: f( t% B( t  File "<pyshell#1>", line 1, in <module>
    ) v4 g, G( Y+ M; W  z- A    req = urllib2.Request(url): F6 |, X& G; S! Y& i0 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
    " g8 q1 |  m/ ~' {0 |>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'3 q! o% s$ k0 c7 g% }2 C8 |" T4 M
    >>> req = urllib2.Request(url ...

    2 ?& C6 z8 p) T" D7 u- k谢谢,解决了

    该用户从未签到

    发表于 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 | 显示全部楼层
    学习了,受益良多。
    8 U3 x% `% Q' E. O1 N, J2 @2 n狂顶楼主。。。

    该用户从未签到

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

    该用户从未签到

    发表于 2015-12-9 14:07:13 | 显示全部楼层
    almighty 楼主,$ l! U8 u. L* G
    可以把这个抓下来离线用吗?
  • 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:37
  • 签到天数: 1992 天

    [LV.Master]伴坛终老

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

    本版积分规则

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

    GMT+8, 2024-4-25 15:59 , Processed in 0.075271 second(s), 11 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2023, Tencent Cloud.

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