掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 93820|回复: 48

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

    [复制链接]

该用户从未签到

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

# H& N1 o" y5 [. \1 l一直想找个英语单词词根和前缀、后缀的词典,主要用来辅助记单词
' K2 f3 O4 i- M5 j比如entombed,如果知道en-,知道tomb,这个单词看一遍就记住了,6 J4 T, e2 h  x5 |. v* v1 P
有点类似汉字的偏旁部首" c  U* s5 P- l8 o4 }& [
找来找去,觉得prefixsuffix.com这个网站还不错,收得比较全,解释比较简明( x. E  _, w) k2 p2 S( n/ H
但是总不能整天老挂在这网站上,得想个能离线浏览的办法
0 ~% V! S5 ^0 |9 Y+ l& |他家倒是出了个app放在appstore上,卖18元,说实话有点小贵,人家SOED6才卖18
  }- U# s, b; _& v$ J) u) ]4 \2 p这还不算,最要命的是从2010年以来这个app一直没更新过,究竟是不再维护了呢?还是已经完美到不用再更新了呢?
* {6 f4 h( t  P. @3 [0 w# Z要知道这几年ios都有过几次重大升级,万一买了和ios7不兼容,闪退怎么办?岂不是白买
) }; {; b0 v8 |
5 N2 g7 i9 X1 O6 o/ A4 T9 ]( z于是想到有没有可能把他家的数据全给扒下来8 o# J: N% [' i) p9 M- v0 A9 n
运气不错,这家网站完全没设防,扒数据的整个过程轻松而愉快. _: z! o5 z( [" ~& [
现在就把这个过程详细讲讲。遇到类似问题可以照猫画虎,把附件的代码改改就能工作
9 Q# r8 x. J) V, s  D6 g) c, H我尽量写得比较啰嗦一点,让计算机小白也能看懂
2 L/ y' G0 o5 T) R9 k% d4 ]/ m, k! I1 i- j0 F  J
一、网页的构造
  M$ @8 x  K8 A* e# t这个网站比较简单,和词根相关的网页就两个
- _/ N  K% Y( t& X- r. n1 h9 E一个是rootchart,点开是张大表,列出最常用的词根' n# d" t4 [1 j
http://www.prefixsuffix.com/rootchart.php?navblks=1011000
/ L* ]" T) R+ V- {; s% d) G还有一个rootsearch,点开有个search选项,可以自己输入词根查询
; \' M' X- E4 a6 J! r+ {- {6 Q! Uhttp://www.prefixsuffix.com/rootsearch.php
6 q* q* a/ H, o. O0 r/ |
& A$ C$ S: E" ~8 h; w二、先搞第一个网页2 [1 ~3 X. x6 }) k! `0 Q. n
地方找到了,如何下手呢?
" }5 h! L. l7 @6 j9 {, a2 t: C第一个简单,直接用脚本请求这个页面,把返回结果接住就行
  1. 2 w! D1 {7 c  G0 s; G1 J# C
  2. url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000', t$ _% ^8 p) {
  3. req = urllib2.Request(url)
    0 _# e8 h! Y5 f
  4. response = urllib2.urlopen(req)' L5 P5 B7 h5 q
  5. page = response.read()
    : ~$ t& \% l8 D1 R( |3 e$ U& b
  6. print page # 打出来看看返回结果究竟是啥玩意3 d6 V' v1 W+ N: {" R( z7 [
复制代码
给计算机小白扫盲
2 z0 L1 o; K5 L互联网的工作原理是这样的:用户向网站发送请求,网站响应请求返回数据7 n) G0 H) Q4 Q6 a
比如用浏览器看网页这样一个最简单的操作:" L  F3 v. p# o" k$ L
输入一个网址按回车,浏览器就向那个网站发送请求;网站返回的网页数据被浏览器接住,经过解析、渲染呈现出来; ]6 j6 q1 o' y* `  w) W/ H
视频啥的也是一个道理,只不过这时候返回的是视频数据,不是网页数据! M$ d& Q8 e* r2 k+ E
这里用脚本发的请求,网站返回的数据自然也能用脚本接到
8 H6 P: s$ T+ U! u  y
* k% W; f+ j7 N6 e
网页数据拿到了,真正需要的那一小块数据在哪呢,这个可以查一下网页的源码,右键菜单->审查元素,如下图
, Q) {" h; P, Z* X( q, [+ g* @1 I' I  x9 z

2 u5 Y; i+ A  d$ \2 R. |5 r可以看到那块数据就在这个大表里面
  1. <table class="affix">...</table>
复制代码
在那一大篇网页数据里把这个表找到,把里面的内容给抠出来,就是一个超强的python库:BeautifulSoup的拿手好戏( u- Z* l8 _* @
(这个库使用起来非常简单,文档也非常完善,有不明白的尽可以去这里查询。这里不再多说。
- H# A& O. T3 p) K9 I2 Qhttp://www.crummy.com/software/B ... 4/doc/index.zh.html
9 O" P; |2 X" f6 p1 H, g, N
" H+ Z, A/ D% p9 m' m! G' o于是有下面的代码
  1. ' q  y$ p# V5 u9 d$ v8 K5 X) ^& a
  2. soup = BeautifulSoup(page)
    4 t: E- E. I! N& v8 g
  3. tb = soup.find('table', {'class': 'affix'}) # 这样就把那个大表给抠出来了& ^$ \5 ~3 V+ V; s+ t
  4. # 然后再一层一层的剥1 f% B. D) A2 {% Z9 Z8 S' D
  5. if tb:1 ~! n$ h  Y- e( N+ D4 |9 t
  6.     rows = tb.findAll('tr') # 所有行
    ' h1 \6 K8 A& b4 |( u
  7.     for tr in rows:5 E7 u5 X6 k3 q/ n+ N9 }- z+ G
  8.        tds = tr.findAll('td') # 每一行的所有列' R: D* T, V6 g0 U  J3 o# o! M# ~
  9.        if tds:
    6 z) W7 I2 U" f0 H7 u* i/ W
  10.               。。。3 v- X: T% I! Q3 m  w. z
复制代码
第一个网页到此解说完毕。
) h& t# W" x" {. l; D5 [$ z博客类、或者外汇牌价,基金公司的每日净值之类的公告信息,都可以用类似的办法扒数据
( x+ V9 P3 l5 n) ?0 v+ A# L& U2 I2 d6 j5 E
三、再搞第二个网页
3 U- M" V/ k6 b( b) G) O这个稍微有点不同,它的工作原理是这样的
1 e; n$ a. X6 |) i& s7 t用户输入关键字,把下拉框和"start","anywhere","end"这两项选好,点击search按钮,2 r0 ?) F8 n- {0 ]
这时候浏览器会向rootsearch.php这个页面发送请求,捎带着还要把用户刚才输入的这些数据给POST过去,# L+ o$ `$ J) G
rootsearch.php收到这些用户数据,才知道要干啥、吐出什么东西回来
5 R" T- U. b& j页面url是已经知道的,那么这里的关键问题就是:浏览器究竟把什么数据给POST过去了呢?
* r7 U' k: v: Q, v$ L' F还是要查一下网页的源码,如下图$ w! q0 j$ U. _

4 I' B$ U; `9 n- M7 q
3 K3 g5 ]' h' c4 z6 D9 G* @可以看到这是一个form,里面有这几个东西正好对应着文本框、下拉框、"start"……:
" R& u) N- J) z, q; y5 T+ Rfield、find、stype
# h! E8 Z! u6 i5 l还有个hidden的东西searching,不晓得是啥,不过没关系,它的value是固定的yes6 B, {- v0 \) [' |* D
给计算机小白扫盲
' y% X1 K! Q; D  e2 p$ ^9 oform叫做提交表单,用来把用户输入的数据提交到网站后台处理2 ~+ `. x4 z5 O
文本框、下拉框、"start"……这些叫做网页控件
* x7 j% N( p, L注意它们的两个属性:name和value,这两个东西都是要提交给后台的,这样网站才知道用户想干嘛

# Q  d) i' Z9 f1 L2 Z, h) ]- a' Y1 h0 Q5 S) n/ P
搞清楚以后,于是有下面的代码

  1. # J& `9 w0 \- t% w! ?$ a; R! l+ v
  2. values = {'field': 'root', 'find': 'ex','searching': 'yes', 'stype': 'anywhere'}: H4 s$ [* v) ~4 P
  3. # 这里模仿用户查询ex这个词缀,输入‘ex’
    # h& D. _7 {: n) a. \% u+ S+ c
  4. # 扒数据自然是出来的越多越好,因此把下拉框选成root,单选按钮选到anywhere* c  |) ~3 `$ L8 o
  5. # 实际上为了扒到所有的数据,我写了26个字母X26个字母的组合,anywhere/start/end各查一遍5 ?5 |  Q3 {, g" U: q0 ~! k" y
  6. # 一共发了26X26X3次请求,比较暴力,这种丑陋的代码就不拿出来现了1 c. [' C4 r% X  K8 Z
  7. data = urllib.urlencode(values)8 @% ]9 \* c9 B
  8. print data # 看看变成了什么,是不是很眼熟?
    8 _. p4 C* B- I* }9 O
  9. req = urllib2.Request(url, data)
    / U4 i1 ?9 e( F  L
  10. page = urllib2.urlopen(req)
    / R5 p' Y( Z  u1 }6 \4 b
  11. print page # 打出来看看这回又是啥玩意7 `6 P" W- L8 ~% c8 t
复制代码
这样就又把数据搞到了,接下来的流程和上面第一个网页的BeautifulSoup那块开始往下一模一样% c! Z% @' E! \# i$ V# M- X( q, w) Z
注:
" g$ s  s6 i; A1 Q像这个网站这样每次检索后刷新整个页面的做法已经不多了,- C7 }5 X5 ~* `/ u1 b% y! ?. H8 U
最近大量的网站使用ajax技术,网站不再返回整个html页面把整篇全部刷新
7 \8 {" W& l# N: E4 Z+ x1 [而是返回一小块html片段,只刷新页面的某一小块,比较环保7 W1 m8 {7 W6 i" {; ^) i
或者干脆只返回一大串数据,用网页的javascript解析、生成html,这种就比较头大,数据看着头晕* q& \8 x1 s8 l7 V) u9 C4 E
* o% m* q5 K. ]' ]  ]5 a
第二个网页到此解说完毕。
; v/ W# r  I( Y1 m5 R4 z9 \" u网站登录类、论坛自动发帖类、订票类、考试报名类、抢沙发类……等等原理上都是这样实现的/ @0 e  _9 |( G' x4 }5 s! L3 N3 _

' ?/ N8 P5 G. d& l1 F) |* H: T% X. l( e1 S& v# L7 E7 B( ]; ]
看到这里你应该想明白了,为什么现在各个网站都要限制连接间隔、用图片验证码
! `- s* b0 g. o+ ?* Y还有用短信发验证码的,有些还搞了数据加密、随机数什么的。。。不这么搞网站服务器就要沦陷了9 {7 b- D  I8 f! v, b3 {& r
所以上面的代码通常会遇到网站的各种阻挠,让你抓不到数据,需要你和网站斗智斗勇
7 n, A9 h3 `- g6 F: @* S2 S) e像图片验证码这玩意最近已经都不太好使了,有人收集大量的验证码图片建特征数据库,一样能突破网站的防线
$ b  \% L$ F1 T于是最近很多网站的图片验证码搞得极其扭曲,以至于本人用肉眼看半天都输错,( O6 L8 I& R) Q  t( K
已经到了人类都无法识别的地步。这种网站估计是留着给外星人用的。  R- ?7 X) A* Y" g8 c9 H. \

, H+ h3 K2 }0 g# ^/ i

本帖子中包含更多资源

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

x

评分

2

查看全部评分

本帖被以下淘专辑推荐:

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

    [LV.1]初来乍到

    发表于 2018-7-28 13:22:31 | 显示全部楼层
    首先,非常感謝樓主。$ X; s, c  \! M( g
    我獲得affix2.txt后,分別用MdxBuilder3.0、4.0X32、x64創建mdx,4.0版都沒問題,但3.0版總是創建失敗,
    $ y' C5 P1 ?# `; o% W- k' H8 ]Done!( o: D7 B( k8 S1 q' m2 e
    Original index size = 0KB, compressed size = 0KB, compression ratio = 314%+ A  U- _; m  q# f
    Time used for this section: 0 seconds
    # g, W7 q# [1 F! j4 X' n! }- h* qBegin processing data contents...
    7 B/ P* {" h9 F$ EFailed to read from source file:C:\Users\frankly\Desktop\affix2.txt for record(line):1
    3 x/ c2 A$ ~, _4 L2 j5 l' YConversion failed!" a3 j/ m* M0 _, a2 [# @8 e
    請各位指教,謝謝。
  • TA的每日心情
    擦汗
    2022-3-12 13:24
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2016-10-12 16:46:54 | 显示全部楼层
    bt4baidu 发表于 2014-6-29 23:27, s+ ]0 q" ~$ C, @/ r
    这种静态网页按我上面的说明毫无压力吧: Z* m* Y; Z1 A: t2 ~
    比如http://www.nsii.org.cn/node/80/A/Acanthus/Acanthus%20leu ...

    ) r1 _/ _( Y# c6 S1 ]4 l# [楼主问一下您的 wish list 上的 英语电子词典都找到了吗?
    + r2 W8 i3 h( t8 @辛苦了
    + L. m# `6 d4 F7 _+ U* p& k如果找到了能不能也给我分享一下? 邮箱[email protected]
    7 i* ]$ |  Q' E. F1 R! {8 q\thanks\a\lot\  :0
    ! S: Y# A$ B0 M: L( P:)

    该用户从未签到

    发表于 2016-5-16 18:10:45 | 显示全部楼层
    楼主发出来的代码好整洁! 学习耶2 {2 e6 Z! r" |! {5 V

    , p$ E' Q" D$ h9 w请教一下 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 | 显示全部楼层
    好贴要顶!" h9 u/ _4 m- I7 E) B7 g
  • TA的每日心情
    开心
    6 小时前
  • 签到天数: 2246 天

    [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 0 [/ ]$ ]4 K3 L0 _
    楼主,请帮忙,这个网站的如何扒http://www.nsii.org.cn/newquery?qs=*:*&fq=kingdom:Plantae ?
    ! `$ C7 v6 t% J2 V3 A& r) E; ^7 U* Y
    这种静态网页按我上面的说明毫无压力吧
    % f' T2 }; b8 S0 [比如http://www.nsii.org.cn/node/80/A ... hus%20leucostachyus) ~4 F2 W& W5 g5 U9 p2 _- u5 g4 r8 y0 C
    这个页面,找到% H+ |, V. G5 a* N& p& [; d- A
    <div class="content clearfix">
    1 I/ c+ A0 e/ D% y: C2 w...& ?  I1 l; ]  y# B: c1 u
    </div>4 ^) _7 f7 c: c4 d
    把里面的东西抠出来就是
  • TA的每日心情
    难过
    2023-11-26 08:44
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2014-6-30 16:49:41 | 显示全部楼层
    本帖最后由 wenlishahsa 于 2014-6-30 16:58 编辑
    + q+ k0 D* w) u+ ~
    ! M. E) I$ u; w4 {: I>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000'* ^4 X; h  ~) I
    >>> req = urllib2.Request(url)# V1 ]3 x1 Q$ p# b1 z
    Traceback (most recent call last):
    ' b- @! r; C7 K: R  File "<pyshell#1>", line 1, in <module>3 R  B9 ?. R3 W: A& `
        req = urllib2.Request(url)
    & n2 V, X, }2 ]' QNameError: 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
    + y% {& ?7 v2 O  Q>>> url = 'http://www.prefixsuffix.com/rootchart.php?navblks=1011000': F  E& O) B' p$ p. h" l9 {# W
    >>> req = urllib2.Request(url ...
    0 [; O" Z$ B2 h8 p. L/ Y
    谢谢,解决了

    该用户从未签到

    发表于 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 | 显示全部楼层
    学习了,受益良多。! z0 N. P! B! l- |
    狂顶楼主。。。

    该用户从未签到

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

    该用户从未签到

    发表于 2015-12-9 14:07:13 | 显示全部楼层
    almighty 楼主,6 `1 C4 ]7 M1 ~7 _
    可以把这个抓下来离线用吗?
  • 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的每日心情
    无聊
    半小时前
  • 签到天数: 1994 天

    [LV.Master]伴坛终老

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

    本版积分规则

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

    GMT+8, 2024-4-27 11:56 , Processed in 0.090232 second(s), 12 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2023, Tencent Cloud.

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