掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 98926|回复: 48

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

    [复制链接]

该用户从未签到

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

3 E( L6 ^5 X. }7 z% a" V; E9 M一直想找个英语单词词根和前缀、后缀的词典,主要用来辅助记单词9 e% c# h4 X$ [  v" f
比如entombed,如果知道en-,知道tomb,这个单词看一遍就记住了,
! a% l. ]2 h3 }& t: ~( k5 |! K! O有点类似汉字的偏旁部首$ e7 t; G( T' j' L9 g
找来找去,觉得prefixsuffix.com这个网站还不错,收得比较全,解释比较简明
7 n0 Q- n/ X% ]" V& c* t但是总不能整天老挂在这网站上,得想个能离线浏览的办法
: A" ]5 e) A  f. W2 `5 r  l& H他家倒是出了个app放在appstore上,卖18元,说实话有点小贵,人家SOED6才卖18
1 }: I; ?6 x/ m这还不算,最要命的是从2010年以来这个app一直没更新过,究竟是不再维护了呢?还是已经完美到不用再更新了呢?
, d. x% i9 L2 H$ G. z# a4 w" e要知道这几年ios都有过几次重大升级,万一买了和ios7不兼容,闪退怎么办?岂不是白买2 \. y. S5 f- [  }% l
! a' [! ~& a, G* t/ ?' Q
于是想到有没有可能把他家的数据全给扒下来
; U  a6 \" p6 }* U: Y6 h运气不错,这家网站完全没设防,扒数据的整个过程轻松而愉快
5 l$ p' t9 z2 W$ j; E* d* z现在就把这个过程详细讲讲。遇到类似问题可以照猫画虎,把附件的代码改改就能工作% r+ p* ~% ~& |) W) C# C* \3 a
我尽量写得比较啰嗦一点,让计算机小白也能看懂0 t& C6 p3 a4 L. k, n* Y
) `2 m% V! n1 J8 r' _) v+ `
一、网页的构造1 u* ?9 n4 _" g7 u
这个网站比较简单,和词根相关的网页就两个, F, n$ q7 @5 x5 K7 \6 V* [
一个是rootchart,点开是张大表,列出最常用的词根
- T" R/ S: `4 l) [& p0 a& Ihttp://www.prefixsuffix.com/rootchart.php?navblks=1011000
# X/ J4 m- Z- E' I9 n. ]还有一个rootsearch,点开有个search选项,可以自己输入词根查询
" p% b8 ]" o6 I* ]* r/ A: c3 Ihttp://www.prefixsuffix.com/rootsearch.php
, `5 e4 f7 K# F3 }6 e( V3 l2 Z9 a" w
二、先搞第一个网页
( N1 x0 W7 Q5 l- a( H地方找到了,如何下手呢?
; q) n& E' W9 j3 d第一个简单,直接用脚本请求这个页面,把返回结果接住就行

  1. 2 B- m; m5 c* S8 ]5 }+ O5 A& E
  2. url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'
    % |$ w$ T" `, ^+ x; P8 }
  3. req = urllib2.Request(url)1 S$ y0 g$ U. W9 ]: N8 b2 }
  4. response = urllib2.urlopen(req)7 d9 T, @& e% W5 S- w7 _" k* I
  5. page = response.read()
    4 E: P4 b( C: \
  6. print page # 打出来看看返回结果究竟是啥玩意
    % h" C8 V& ~4 g; Q1 ^0 \4 F
复制代码
给计算机小白扫盲
/ T: j8 ^9 ^. k2 ]7 B' V, Z( ?# w  y互联网的工作原理是这样的:用户向网站发送请求,网站响应请求返回数据
" r( J% G# W% v) E/ c9 m比如用浏览器看网页这样一个最简单的操作:
  m+ X/ [2 t4 R; O# l& Y" h/ g4 V2 |5 e& A输入一个网址按回车,浏览器就向那个网站发送请求;网站返回的网页数据被浏览器接住,经过解析、渲染呈现出来9 L' V/ B; x. G9 `; c* t5 x0 N
视频啥的也是一个道理,只不过这时候返回的是视频数据,不是网页数据* ]) s0 s4 F3 H; Y+ n5 G% Z
这里用脚本发的请求,网站返回的数据自然也能用脚本接到

( p' ~" I/ Z+ j9 G1 ?* g: y; G3 W! |/ I0 z
网页数据拿到了,真正需要的那一小块数据在哪呢,这个可以查一下网页的源码,右键菜单->审查元素,如下图
0 B+ l; c* r7 W) Y% Q& o! K1 q/ n" F$ |+ w1 L

( Z0 d1 X/ S1 J. R: ^2 D5 ]可以看到那块数据就在这个大表里面
  1. <table class="affix">...</table>
复制代码
在那一大篇网页数据里把这个表找到,把里面的内容给抠出来,就是一个超强的python库:BeautifulSoup的拿手好戏7 v* J$ Z1 ^; x/ y0 N+ H
(这个库使用起来非常简单,文档也非常完善,有不明白的尽可以去这里查询。这里不再多说。
/ I4 L1 b! f8 g3 \6 K0 F$ N% Hhttp://www.crummy.com/software/B ... 4/doc/index.zh.html)
! e2 }# b( ]0 |0 y/ x& P& F) U) X
9 D) o- _/ C3 Y! i于是有下面的代码

  1. 4 w  @2 ?6 P" E. C/ {& `1 d
  2. soup = BeautifulSoup(page)
    1 ]+ P- e5 @% `5 B  q
  3. tb = soup.find('table', {'class': 'affix'}) # 这样就把那个大表给抠出来了0 Z6 B9 A& t- |& R
  4. # 然后再一层一层的剥
    ) x% i! K6 H$ ?; u# R  o$ e
  5. if tb:
    , |# L) ~5 u* z8 @2 W- g
  6.     rows = tb.findAll('tr') # 所有行# w4 |' N* r( R9 ^) _+ n/ c7 N3 z9 x$ }
  7.     for tr in rows:
    1 e% j& E: S, L+ Q) W
  8.        tds = tr.findAll('td') # 每一行的所有列
    ' H8 p/ o  k+ ^1 @4 p5 }/ M
  9.        if tds:
    7 D6 e; l: U2 p
  10.               。。。
    & {8 ], w- I2 L$ I- R
复制代码
第一个网页到此解说完毕。% i+ ?2 C2 {5 G
博客类、或者外汇牌价,基金公司的每日净值之类的公告信息,都可以用类似的办法扒数据$ q  ]/ ?4 U# ^3 O! e7 _
( I5 ^- ^/ O* x: ]8 O# y7 ~
三、再搞第二个网页: P9 K0 ~6 F) r7 l  M! A  ^; A! n
这个稍微有点不同,它的工作原理是这样的% I! O* L3 e3 J' n. B* y9 v
用户输入关键字,把下拉框和"start","anywhere","end"这两项选好,点击search按钮,
  b  b1 G  q! K- s: {这时候浏览器会向rootsearch.php这个页面发送请求,捎带着还要把用户刚才输入的这些数据给POST过去,
' j3 M- U1 `' n+ vrootsearch.php收到这些用户数据,才知道要干啥、吐出什么东西回来
% i) k4 h, ?+ C/ T, E0 E+ S页面url是已经知道的,那么这里的关键问题就是:浏览器究竟把什么数据给POST过去了呢?
" E% w$ L) e% l8 z# H- N6 q还是要查一下网页的源码,如下图
* D* B  c% O2 M+ f7 ?0 I8 S' h# J% P- K' D+ a
; f: o' O: l# j& m+ t8 [
可以看到这是一个form,里面有这几个东西正好对应着文本框、下拉框、"start"……:6 v7 Z+ o6 A7 r6 g7 i3 w
field、find、stype# K7 r0 g, ]' y7 x, O2 O0 m
还有个hidden的东西searching,不晓得是啥,不过没关系,它的value是固定的yes9 E& m. T5 m. N- T7 t: W9 C
给计算机小白扫盲5 Z& O) X( m: M8 |/ g' L' e
form叫做提交表单,用来把用户输入的数据提交到网站后台处理2 q( r3 M4 b2 ^" B  {! ]. B  G
文本框、下拉框、"start"……这些叫做网页控件% Q  u+ o& s  l) Q6 z, f
注意它们的两个属性:name和value,这两个东西都是要提交给后台的,这样网站才知道用户想干嘛

3 z0 }2 a, m- r. A. N7 g9 c" q* s/ R% A& z$ L$ x
搞清楚以后,于是有下面的代码

  1. 4 b$ W7 O7 s: ]& D$ u
  2. values = {'field': 'root', 'find': 'ex','searching': 'yes', 'stype': 'anywhere'}
    2 }8 s! F5 M; W# O
  3. # 这里模仿用户查询ex这个词缀,输入‘ex’% H) Q8 s  m8 Q0 X1 ^& w) A
  4. # 扒数据自然是出来的越多越好,因此把下拉框选成root,单选按钮选到anywhere. ^! j- u% ]  j( V8 X
  5. # 实际上为了扒到所有的数据,我写了26个字母X26个字母的组合,anywhere/start/end各查一遍6 e4 `- |- a" i8 H& _1 @
  6. # 一共发了26X26X3次请求,比较暴力,这种丑陋的代码就不拿出来现了
    ; a5 r( u* V7 @
  7. data = urllib.urlencode(values)
    2 [* r" E( ]4 T4 p) H" U7 y) H
  8. print data # 看看变成了什么,是不是很眼熟?& h% n- {) @1 ~5 }3 C# H5 C! p
  9. req = urllib2.Request(url, data)
    9 P5 O. z. W+ L; `: W) g1 b
  10. page = urllib2.urlopen(req)
    7 A* n' g* S4 H( M
  11. print page # 打出来看看这回又是啥玩意
    / f- Q' l6 e' v8 Y' Q8 n/ G8 ~
复制代码
这样就又把数据搞到了,接下来的流程和上面第一个网页的BeautifulSoup那块开始往下一模一样
% F1 N3 L& M2 R) j1 w注:, v% ]/ A# s& x1 v) p* w
像这个网站这样每次检索后刷新整个页面的做法已经不多了,5 S" r- i, Y  e2 E! I% B* |
最近大量的网站使用ajax技术,网站不再返回整个html页面把整篇全部刷新
5 i9 K7 @) o( N& I而是返回一小块html片段,只刷新页面的某一小块,比较环保: Q2 F) K( _8 l9 Y. B
或者干脆只返回一大串数据,用网页的javascript解析、生成html,这种就比较头大,数据看着头晕+ X7 n5 ^9 W8 L

* m4 A2 e( e0 `% F  D第二个网页到此解说完毕。9 H# j2 j  @/ ?8 U0 v0 Q
网站登录类、论坛自动发帖类、订票类、考试报名类、抢沙发类……等等原理上都是这样实现的
+ l) r$ M' d6 V' }5 z
+ e7 }4 @* X0 |6 l1 V5 ^( G$ b% H( y& N& O. ]5 ^- ]
看到这里你应该想明白了,为什么现在各个网站都要限制连接间隔、用图片验证码
1 D/ d! |  v' A7 l还有用短信发验证码的,有些还搞了数据加密、随机数什么的。。。不这么搞网站服务器就要沦陷了
) U5 y' u+ x$ w" J" L所以上面的代码通常会遇到网站的各种阻挠,让你抓不到数据,需要你和网站斗智斗勇& L) r' \# h, |, [
像图片验证码这玩意最近已经都不太好使了,有人收集大量的验证码图片建特征数据库,一样能突破网站的防线1 q/ K" x* J- \" T% e3 Z+ k
于是最近很多网站的图片验证码搞得极其扭曲,以至于本人用肉眼看半天都输错,
  [7 _8 j8 v; h2 j6 w+ E已经到了人类都无法识别的地步。这种网站估计是留着给外星人用的。
+ x4 N* m& P8 f* d5 B  ^# u) d

本帖子中包含更多资源

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

x

评分

2

查看全部评分

本帖被以下淘专辑推荐:

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

    [LV.1]初来乍到

    发表于 2018-7-28 13:22:31 | 显示全部楼层
    首先,非常感謝樓主。3 G! V# h5 |, Y5 \3 h' w
    我獲得affix2.txt后,分別用MdxBuilder3.0、4.0X32、x64創建mdx,4.0版都沒問題,但3.0版總是創建失敗,, t/ v4 r; K8 w
    Done!- ~" w2 ]! y3 K/ K- }7 c1 K& F
    Original index size = 0KB, compressed size = 0KB, compression ratio = 314%0 m# b" d* P9 I! R* e( a% R
    Time used for this section: 0 seconds; G7 [' Q% U$ d6 m# g  _
    Begin processing data contents...
    3 t$ A6 n* n$ `. AFailed to read from source file:C:\Users\frankly\Desktop\affix2.txt for record(line):1) X; ~# ^( X% u" q' m! ~
    Conversion failed!
    % [& \* ~# d. B) O$ I' d  V( g請各位指教,謝謝。
  • TA的每日心情
    擦汗
    2022-3-12 13:24
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2016-10-12 16:46:54 | 显示全部楼层
    bt4baidu 发表于 2014-6-29 23:27
    ; P9 N* f: E: v# m7 G6 L这种静态网页按我上面的说明毫无压力吧
    7 c: F- y! {. b0 y" H' C7 ^比如http://www.nsii.org.cn/node/80/A/Acanthus/Acanthus%20leu ...
    ) X9 s* ?2 j5 a; {; E
    楼主问一下您的 wish list 上的 英语电子词典都找到了吗?
    - P3 z% q) a" H, j8 R0 Y辛苦了
    1 W5 L$ W, }8 N, }" `& s$ r如果找到了能不能也给我分享一下? 邮箱[email protected] : ~. u7 y: L! a
    \thanks\a\lot\  :0 6 _* T# ~5 Y5 B& T* Y( f
    :)

    该用户从未签到

    发表于 2016-5-16 18:10:45 | 显示全部楼层
    楼主发出来的代码好整洁! 学习耶% u, e0 I$ e: o3 q$ r$ U+ }8 B

    + N6 k; Y5 a1 b: ]: O请教一下 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 | 显示全部楼层
    好贴要顶!
    9 @' N9 f1 ?$ h) e! b2 x
  • TA的每日心情
    开心
    2026-5-17 05:44
  • 签到天数: 2908 天

    [LV.Master]伴坛终老

    发表于 2014-6-18 09:10:56 | 显示全部楼层
    以前的百度百科2012,有30g,现在已经不更新了,如果楼主出新版,那可是大好事啊,预祝成功!
  • 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 * L- \8 \, `9 n8 _, x8 \
    楼主,请帮忙,这个网站的如何扒http://www.nsii.org.cn/newquery?qs=*:*&fq=kingdom:Plantae ?
    7 \. X  J, o6 \  w1 j
    这种静态网页按我上面的说明毫无压力吧
    % F( T& c$ p) X6 [* J  E5 U( C0 D比如http://www.nsii.org.cn/node/80/A ... hus%20leucostachyus$ a* E3 Y% k  p( E
    这个页面,找到
    3 g1 Z6 t2 }; d4 s<div class="content clearfix">
    ' f( y; H3 ?/ n2 y7 N...2 |! `! w' H' q' n5 s3 G( S
    </div>
    ; _: Y2 q, v6 g4 q; U* X9 q: ^把里面的东西抠出来就是
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-30 16:49:41 | 显示全部楼层
    本帖最后由 wenlishahsa 于 2014-6-30 16:58 编辑
    1 `$ {  J  r' }, q# g5 ^2 E3 h& v$ a! S9 E& d( d* h1 f
    >>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'8 \2 t4 p- A' H7 @9 y4 P
    >>> req = urllib2.Request(url)' {0 l2 d* q! k& O
    Traceback (most recent call last):
    % ?* m6 Y# r5 W( p0 c5 N  File "<pyshell#1>", line 1, in <module>
    , V: l% A5 v! C9 _1 N5 Q7 Q/ A; }    req = urllib2.Request(url)
    3 {8 D/ J) D  Q8 K: CNameError: name 'urllib2' is not defined>>> 楼主,请问,为什么我照你的执行会出错呢?
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-30 18:30:34 | 显示全部楼层
    wenlishahsa 发表于 2014-6-30 16:49
    5 N0 p+ X/ [7 H' w% k$ C>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'
    ; V* z" \- R! U& S>>> req = urllib2.Request(url ...
      m3 G. Q# x& L. R1 |- B. _7 Y$ x
    谢谢,解决了

    该用户从未签到

    发表于 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 | 显示全部楼层
    学习了,受益良多。# O# u' ]8 k0 D1 k9 K
    狂顶楼主。。。

    该用户从未签到

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

    该用户从未签到

    发表于 2015-12-9 14:07:13 | 显示全部楼层
    almighty 楼主,
    5 H' x, l# l% ^% ^1 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:21
  • 签到天数: 2866 天

    [LV.Master]伴坛终老

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

    本版积分规则

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

    GMT+8, 2026-10-15 09:05 , Processed in 0.030380 second(s), 30 queries .

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

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