掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 95174|回复: 48

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

    [复制链接]

该用户从未签到

发表于 2014-6-17 19:21:42 | 显示全部楼层 |阅读模式
9 V: ~; ~( v1 ~# K( s4 l# x
一直想找个英语单词词根和前缀、后缀的词典,主要用来辅助记单词
4 I- J+ D& M4 l  R- i7 K6 y8 O比如entombed,如果知道en-,知道tomb,这个单词看一遍就记住了,1 m" X, G2 ]7 g9 @1 h, `
有点类似汉字的偏旁部首
8 [8 A( ^0 a" c0 z找来找去,觉得prefixsuffix.com这个网站还不错,收得比较全,解释比较简明
0 I# u0 c2 E  D5 _3 j. y但是总不能整天老挂在这网站上,得想个能离线浏览的办法" y( t/ @( S1 ~3 O& M
他家倒是出了个app放在appstore上,卖18元,说实话有点小贵,人家SOED6才卖18
4 {! @& ?( {- l这还不算,最要命的是从2010年以来这个app一直没更新过,究竟是不再维护了呢?还是已经完美到不用再更新了呢?) |2 b4 I; Z' B% _0 Q: T
要知道这几年ios都有过几次重大升级,万一买了和ios7不兼容,闪退怎么办?岂不是白买( f# A1 }  a6 j1 c

* H7 y# }/ C7 d# _( `/ b+ {于是想到有没有可能把他家的数据全给扒下来0 M7 L# C" A1 \  w1 w
运气不错,这家网站完全没设防,扒数据的整个过程轻松而愉快
. [, T$ m' y' I9 b2 K% x- N( s现在就把这个过程详细讲讲。遇到类似问题可以照猫画虎,把附件的代码改改就能工作
1 p1 J; ~1 I  t; A: I* A( `# l我尽量写得比较啰嗦一点,让计算机小白也能看懂
' }/ J' i6 k$ Y# z5 S% y3 S% i# x; {% R
一、网页的构造5 T! F$ c5 j0 S" _+ }9 Z
这个网站比较简单,和词根相关的网页就两个
9 r0 n: o- e! F1 U8 X+ N' z一个是rootchart,点开是张大表,列出最常用的词根+ @* O0 l. ?6 o" i  L
http://www.prefixsuffix.com/rootchart.php?navblks=10110005 v* @( R: J5 Y. @1 _
还有一个rootsearch,点开有个search选项,可以自己输入词根查询
" [7 T/ R/ [6 xhttp://www.prefixsuffix.com/rootsearch.php
+ V+ \: C- ~  G" i+ w$ \, X# N3 }$ F: x: J" a6 s( B) B. d$ D' ]
二、先搞第一个网页
# |- _/ M8 J) W  Q' ~地方找到了,如何下手呢?
! q/ a% j3 B! k$ Q& f! t第一个简单,直接用脚本请求这个页面,把返回结果接住就行
  1. 4 l' }) _" p# t# t( y
  2. url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'
    # U: D* [3 X" {, l: J
  3. req = urllib2.Request(url)+ u9 ^! s3 C& ]+ f  o0 w
  4. response = urllib2.urlopen(req); }$ b: h- @9 j. X4 K
  5. page = response.read()
    5 v; ]# B. @: Y# X" J+ C
  6. print page # 打出来看看返回结果究竟是啥玩意% O+ o5 E+ J7 m! k+ A3 g" F4 G
复制代码
给计算机小白扫盲6 X) C. y& ?, K, B
互联网的工作原理是这样的:用户向网站发送请求,网站响应请求返回数据
" M0 }- B3 {- `* ?) D比如用浏览器看网页这样一个最简单的操作:
1 S' V& \8 l" B" H输入一个网址按回车,浏览器就向那个网站发送请求;网站返回的网页数据被浏览器接住,经过解析、渲染呈现出来$ }; M& M+ K) \. H1 D
视频啥的也是一个道理,只不过这时候返回的是视频数据,不是网页数据
6 x" w; F) R$ P  j6 _- {, G这里用脚本发的请求,网站返回的数据自然也能用脚本接到
. O  j, ]% G5 A0 y
; T+ Z( Z* A1 A% n0 @, p
网页数据拿到了,真正需要的那一小块数据在哪呢,这个可以查一下网页的源码,右键菜单->审查元素,如下图
: v# x% h% C1 C4 o+ O5 d* U9 t; D% {5 F; h
/ ~" w+ e, G- o
可以看到那块数据就在这个大表里面
  1. <table class="affix">...</table>
复制代码
在那一大篇网页数据里把这个表找到,把里面的内容给抠出来,就是一个超强的python库:BeautifulSoup的拿手好戏
( H' A; W6 ~, D* M7 U(这个库使用起来非常简单,文档也非常完善,有不明白的尽可以去这里查询。这里不再多说。
9 @  y) H: [0 x1 q" uhttp://www.crummy.com/software/B ... 4/doc/index.zh.html- P# F3 x8 Y7 @# l  j
. g8 r- |7 Q% w( v9 e) k  F, `
于是有下面的代码

  1. 9 q: V9 |8 M5 J4 v
  2. soup = BeautifulSoup(page): ?- e# G& G3 E4 n' d: a
  3. tb = soup.find('table', {'class': 'affix'}) # 这样就把那个大表给抠出来了0 e& s4 V; T0 N9 U6 {
  4. # 然后再一层一层的剥
    . T( _( x. v! B! z
  5. if tb:
    2 s7 i: c2 S' }
  6.     rows = tb.findAll('tr') # 所有行) Y4 ^! }+ M" U$ Z. i
  7.     for tr in rows:
    9 C8 A7 y9 M- a9 V9 M* Z
  8.        tds = tr.findAll('td') # 每一行的所有列
    6 z" Y1 B. w1 g- |" b8 g
  9.        if tds:
    / {# I. K9 T4 A% c: m4 A6 S
  10.               。。。# K% L3 N4 j" r% ?
复制代码
第一个网页到此解说完毕。
3 |2 J& L- V. b; T$ ~博客类、或者外汇牌价,基金公司的每日净值之类的公告信息,都可以用类似的办法扒数据) O2 p* \) Q9 ~& D7 B. A" U

0 l3 L. Z: d- y) f7 k3 `8 A三、再搞第二个网页( c* d' @' U' Z0 K
这个稍微有点不同,它的工作原理是这样的
- r. Y2 ^$ A8 Y* u- w7 B1 l: D! |用户输入关键字,把下拉框和"start","anywhere","end"这两项选好,点击search按钮,
: m2 `7 Q/ s1 \3 }4 y3 F. Y6 P( T这时候浏览器会向rootsearch.php这个页面发送请求,捎带着还要把用户刚才输入的这些数据给POST过去,  g) s* B; x1 C4 m* A: q0 g
rootsearch.php收到这些用户数据,才知道要干啥、吐出什么东西回来: g$ ?, q1 l3 ^1 g  F9 x
页面url是已经知道的,那么这里的关键问题就是:浏览器究竟把什么数据给POST过去了呢?
) L8 Z: e% G' n6 q# ?还是要查一下网页的源码,如下图8 q! n  I, d) J" x$ Z! m& v
% T/ Z; }5 o/ }
0 @0 ^- r& x5 U7 F0 b: X& M
可以看到这是一个form,里面有这几个东西正好对应着文本框、下拉框、"start"……:
& P: K, {1 f* m+ }: Y: k3 s2 Yfield、find、stype" C  U- Z# p0 D
还有个hidden的东西searching,不晓得是啥,不过没关系,它的value是固定的yes
6 x4 z" [) _  |( r4 V: V  h( @给计算机小白扫盲0 H# [) Z) B+ Y- i
form叫做提交表单,用来把用户输入的数据提交到网站后台处理3 k- i+ U( N$ k  k
文本框、下拉框、"start"……这些叫做网页控件+ I$ g+ F; b' U6 D7 ~! g
注意它们的两个属性:name和value,这两个东西都是要提交给后台的,这样网站才知道用户想干嘛

. l( D, s5 Y$ p5 t) v) f7 z& s. v+ ?; m
搞清楚以后,于是有下面的代码
  1. , f& G5 u* P# W7 I9 |* {* k
  2. values = {'field': 'root', 'find': 'ex','searching': 'yes', 'stype': 'anywhere'}* t2 X3 ^  r& @$ F) j7 s- d$ K+ E
  3. # 这里模仿用户查询ex这个词缀,输入‘ex’
    # O8 {4 ~1 H: D
  4. # 扒数据自然是出来的越多越好,因此把下拉框选成root,单选按钮选到anywhere. ^7 A7 w- ]: o( \* v0 V3 j; w* u
  5. # 实际上为了扒到所有的数据,我写了26个字母X26个字母的组合,anywhere/start/end各查一遍$ ?. H$ f/ g/ L4 k* v8 r
  6. # 一共发了26X26X3次请求,比较暴力,这种丑陋的代码就不拿出来现了# A2 a5 J. e7 K0 F& W$ y/ Q
  7. data = urllib.urlencode(values)6 d7 S# ?( q4 J. p% \! H
  8. print data # 看看变成了什么,是不是很眼熟?
    : B; t$ T. n- v, j5 n
  9. req = urllib2.Request(url, data)
    " h! a. Q1 _4 Z6 S
  10. page = urllib2.urlopen(req)2 B% k1 b9 q3 V+ c$ ~8 t
  11. print page # 打出来看看这回又是啥玩意
    4 Q' @7 @& J9 ?: |7 @. X& l7 l
复制代码
这样就又把数据搞到了,接下来的流程和上面第一个网页的BeautifulSoup那块开始往下一模一样
$ T: J8 U6 g  A3 w* X注:1 ]8 [& n0 L( r. }- Z
像这个网站这样每次检索后刷新整个页面的做法已经不多了,9 D) S5 f$ u0 G$ Y( d0 w4 D
最近大量的网站使用ajax技术,网站不再返回整个html页面把整篇全部刷新" Z  H% i% ]6 l0 Z* O& T/ j% Z  n
而是返回一小块html片段,只刷新页面的某一小块,比较环保/ A; D: A' Q: P) r* y! m: k
或者干脆只返回一大串数据,用网页的javascript解析、生成html,这种就比较头大,数据看着头晕& l( `, \- I" {/ C- [

, G& A: m6 k9 X第二个网页到此解说完毕。4 i2 H, b: c. q1 u. X) T2 l# A
网站登录类、论坛自动发帖类、订票类、考试报名类、抢沙发类……等等原理上都是这样实现的0 W- [' x+ I& A1 p- F( f2 s
# r) V. ^' A. H. G4 J7 i$ u9 ?

( I* A$ v6 z3 S) A: P* j  {2 o) {看到这里你应该想明白了,为什么现在各个网站都要限制连接间隔、用图片验证码
; O; c# Y0 x+ D) G& U3 l# t, R还有用短信发验证码的,有些还搞了数据加密、随机数什么的。。。不这么搞网站服务器就要沦陷了
$ w8 J) `* J* _' v) ?/ u* m+ l% @所以上面的代码通常会遇到网站的各种阻挠,让你抓不到数据,需要你和网站斗智斗勇
# U+ y3 L) [) n6 Y' W# r0 i% X) H1 j5 Y像图片验证码这玩意最近已经都不太好使了,有人收集大量的验证码图片建特征数据库,一样能突破网站的防线7 Q/ a+ _/ ~. R. V7 I2 }  r4 t4 s
于是最近很多网站的图片验证码搞得极其扭曲,以至于本人用肉眼看半天都输错,% P8 p8 F. l6 l. k" Q
已经到了人类都无法识别的地步。这种网站估计是留着给外星人用的。3 P8 B# x0 q- m
; A3 x7 |$ W) i' `9 Q# ^/ y& w

本帖子中包含更多资源

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

x

评分

2

查看全部评分

本帖被以下淘专辑推荐:

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

    [LV.1]初来乍到

    发表于 2018-7-28 13:22:31 | 显示全部楼层
    首先,非常感謝樓主。
    2 e8 u) I" O! R我獲得affix2.txt后,分別用MdxBuilder3.0、4.0X32、x64創建mdx,4.0版都沒問題,但3.0版總是創建失敗,6 P7 c  K# N! b8 ~4 x: \, d
    Done!$ ~, p+ S6 x! i# ~) X* f0 G
    Original index size = 0KB, compressed size = 0KB, compression ratio = 314%% T; k- |8 Q, \1 w
    Time used for this section: 0 seconds' j  V) L1 j! a) l* \& s1 f
    Begin processing data contents...' h9 l$ y  A; O$ P  K
    Failed to read from source file:C:\Users\frankly\Desktop\affix2.txt for record(line):1
    1 ?2 Y" v. o) f/ e9 a! ZConversion failed!
    4 m# f% ^) v( }請各位指教,謝謝。
  • TA的每日心情
    擦汗
    2022-3-12 13:24
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2016-10-12 16:46:54 | 显示全部楼层
    bt4baidu 发表于 2014-6-29 23:27
    7 G4 ]: w: z; G. r这种静态网页按我上面的说明毫无压力吧0 M( z1 ~2 a$ c# G. }, k$ y
    比如http://www.nsii.org.cn/node/80/A/Acanthus/Acanthus%20leu ...

    . z0 y! e' z8 u5 \/ T0 J1 L楼主问一下您的 wish list 上的 英语电子词典都找到了吗?2 ^+ h- a$ C0 w3 R3 O0 {* N
    辛苦了6 r- R0 L" @* p  E3 w
    如果找到了能不能也给我分享一下? 邮箱[email protected] ! l* M3 M; J- z/ I
    \thanks\a\lot\  :0
    , ~) f2 _1 l* n! D" ~* B, p; q( O# a9 d:)

    该用户从未签到

    发表于 2016-5-16 18:10:45 | 显示全部楼层
    楼主发出来的代码好整洁! 学习耶
    2 Y. [5 M6 D8 u# C% l) w" y( D1 G7 {* A- D/ z0 H% x
    请教一下 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 | 显示全部楼层
    好贴要顶!
    1 i1 c/ W+ ?8 B3 w6 s
  • TA的每日心情
    开心
    4 小时前
  • 签到天数: 2579 天

    [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
    ) w/ x% l% Z* H- W- O+ o楼主,请帮忙,这个网站的如何扒http://www.nsii.org.cn/newquery?qs=*:*&fq=kingdom:Plantae ?
      [2 `# P0 H  D  H% O' B
    这种静态网页按我上面的说明毫无压力吧) H5 t' p% N* [8 b* ]8 y
    比如http://www.nsii.org.cn/node/80/A ... hus%20leucostachyus
    ) J$ s$ I( c  h这个页面,找到
    9 [7 B/ h9 a8 M- I& I+ W) V<div class="content clearfix">; f# J/ S4 c% p! q7 g5 x2 X
    ...
    ! n0 r* w) `% {7 v</div>
    6 ~8 N: C, s( H6 k2 y; u# w7 R' I把里面的东西抠出来就是
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-30 16:49:41 | 显示全部楼层
    本帖最后由 wenlishahsa 于 2014-6-30 16:58 编辑
    % k& I* ]7 W2 u0 {0 K
    . ]7 b' n6 b" ]  B4 s>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'
    , K' S: y7 w3 z, M+ t>>> req = urllib2.Request(url)
    1 f9 Y4 _3 a9 t' u1 q1 oTraceback (most recent call last):
    " @" A/ y. _& A7 N6 v  File "<pyshell#1>", line 1, in <module>
    7 U% G. E) p+ d% J. J    req = urllib2.Request(url)
      s7 b, I" H' E: {7 E$ ^3 G) b: m  xNameError: 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 D# ]4 ^7 L9 h1 Q
    >>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'& l) ?+ u2 p' n& @/ ^# \
    >>> req = urllib2.Request(url ...
    4 a; i' L+ P# ]: K/ ~: v3 q" |
    谢谢,解决了

    该用户从未签到

    发表于 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 | 显示全部楼层
    学习了,受益良多。
    6 k5 k/ o& w" I3 s/ q0 t狂顶楼主。。。

    该用户从未签到

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

    该用户从未签到

    发表于 2015-12-9 14:07:13 | 显示全部楼层
    almighty 楼主,
    & c  K$ ^& @  X0 o# [可以把这个抓下来离线用吗?
  • 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的每日心情
    无聊
    1 小时前
  • 签到天数: 2349 天

    [LV.Master]伴坛终老

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

    本版积分规则

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

    GMT+8, 2025-5-6 23:20 , Processed in 0.025514 second(s), 27 queries .

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

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