QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5441|回复: 1
打印 上一主题 下一主题

[个人总经验] Python爬虫仅需一行代码----crawl第三方库

[复制链接]
字体大小: 正常 放大

326

主题

32

听众

1万

积分

  • TA的每日心情
    慵懒
    2020-7-12 09:52
  • 签到天数: 116 天

    [LV.6]常住居民II

    管理员

    群组2018教师培训(呼和浩

    群组2017-05-04 量化投资实

    群组2017“草原杯”夏令营

    群组2018美赛冲刺培训

    群组2017 田老师国赛冲刺课

    跳转到指定楼层
    1#
    发表于 2020-6-2 16:00 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    仅需一行代码写爬虫–simple_crawl
      {7 j% ]' @/ e* b7 e; }. R# E% A9 e9 I9 csimple_crawl
    8 Q- w3 i0 M5 l, i+ r5 M2 j8 o0 u仅需一行代码即可达到爬虫效果: R$ x9 H% \  J3 x+ h% _
    项目地址(欢迎star):https://github.com/Amiee-well/crawl
    ' ]' t$ p6 d1 w使用方法6 F' c% i0 o! n7 G
    pip install simple_crawl5 M& r- y! r* f% E

    4 v9 H. f3 C3 |$ V% y# d0 q; V### 以下源代码为简单介绍,详细功能介绍再源代码之下
    8 S/ D0 |! a; c: N2 P  e+ Mfrom simple_crawl import request
    ) J' K, T6 y. s0 W# V7 ?% krequest.parse(+ @+ m1 ^1 z. q* J  o& ^. [- A
            # status 参数为运行状态,支持单线程多线程多进程协程以及联合
    6 N* \2 e! I8 y        status="aiohttp",
    9 V; o: M# h& i        # url 参数为爬虫网址,单线程状态为字符串格式,特殊状态为列表格式
    7 V5 l. x$ u+ a* P5 p7 w# h        url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],, j& _8 K7 W. l5 R6 M
            # login 参数为获取登陆信息,如淘宝等网址需要登陆信息5 W9 W' H/ v1 ^) J) G' l% }
        #login="taobao",1 F" [4 D' C7 |8 \5 \, k
        # type_url 参数为返回源代码格式,支持text和json,默认返回text
    " M' W8 x  w& P7 l5 p    type_url = "text",) g0 N3 Z! G: A. G. w- O1 Y4 o
        # Parsing 参数为解析方法,支持re、xpath和beautifulsoup/ ^; Y( O9 W4 M0 r( B* v
        Parsing = 'xpath',
    4 @9 p7 \1 a& W    # label 参数为爬虫解析过程,字典格式,详情见下方
    5 N  P4 c& ^/ m# b; o' X    label = {+ x& }- ^) P* v* ^0 r0 e+ o4 V
                'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
    7 A2 q& C1 Y- G0 g6 e" Q: K            'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],; u, x2 k) z% G( e
                'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
    / x* }9 h' h8 r5 i, ~  Y     },
    1 c& ]: g3 }8 ]! K% e8 W% p     # write 参数为爬虫结果保存,支持txt、csv、pkl、json,注:特殊状态爬虫信息容易混乱3 y/ j7 z  I/ J
         write='result.txt',9 L) ~6 C( J' R: h7 ?
         # next_url 参数为下一页爬虫地址,@必须为href,仅支持单线程爬虫
    9 o8 `& ^' p2 e8 o/ e/ n/ z; [, @     next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',. [- d4 J' Q- c: v' a( a
         # page 参数为断续笔记,第一个参数是否启用笔记,第二个参数选填默认page.txt,仅支持单线程爬虫# S  A" T) T( _  t
         page=[True,"now_url.txt"],
    - E4 Z% Z* z) j2 `) U$ r2 x  q9 I( g     # clean 参数为是否进行数据清洗,防止大量爬虫收集无用信息
    8 x8 u2 K5 t: b  s     #clean=True,7 w8 E" d1 f' `( ~# L
         # texting 参数为是否选择连续爬虫,避免爬虫过程中出现非代码问题报错结束爬虫程序2 }/ k5 I  ^5 y# v0 Z( c, i
         texting=True,
    ! M! A3 `% F) O! t2 z+ v     # Thread_num 为多线程数,默认为1单线程,支持多线程状态和异步状态5 L0 ~1 w' D# ~% i0 I4 b  ]. s
         Thread_num=3,
    3 q& g. g4 n( V- {. I- l: ]( m; K! p     # cpu_count 为多进程数,默认为1单进程,支持多进程状态和联合状态1 B3 G6 A5 b1 V$ c/ z9 x8 |
         cpu_count=1,3 J# M1 G- v  {
         # sem 为异步控制数,默认为5同时启动,支持异步状态和联合状态
    6 b- K3 V) [" g# e+ E9 I     sem=5,0 j5 w0 ^) u4 z- `
         # write_SQL 为是否写入数据库,默认否
    4 N2 M3 w- d3 N4 S+ C. i4 o     # host 参数默认localhost* v2 C* p) j5 G" p7 m
         # post 参数默认3306
    ) B  ]1 w5 L: F4 c- A4 U     # user 参数默认root. F+ k# H* Z& q" m/ I1 V" B- n
         # password 参数必填,必须正确
    / ]* G$ I6 c( g/ m6 a& E1 T$ ?     # db 参数为即将存入的数据库名,若不存在自动创建
    8 [0 @4 {# w, y6 A     # table 参数为即将存入的数据表名,若不存在自动创建
      w) j  E& ~# ?3 @     write_SQL={
    7 ~0 @* P, V$ q5 C- W         'host':'localhost',
    8 x  f, \+ V8 R; V% a         'post':'3306',4 ^2 V: a# c; {" a
             'user':'root',7 E$ d, w6 E( p, v0 a; ?6 `2 ^
             'password':'123456',3 N# Y& M$ E) |- J* m
             'db':'example',' E3 w( Q" M! y8 f+ G6 \
             'table':'example') ^6 r1 K6 m8 x( u! l* [3 E- F
          }
    1 Q8 s, M$ R7 A1 w. F).run()3 Y1 j/ }. d2 V0 }# r
    ( A) G% y( {. u8 N3 w" }
    介绍一下crawl参数设置:
    , s- C+ X  E5 f8 L  Z' f$ h
    7 ^) o) ?: x* y: k'''
    " q( E" b' U: k6 o6 s1 B单行代码爬虫程序执行7 s% o. h- c8 }% _6 l. f% C+ `
    :param status:启用爬虫类型,支持普通爬虫、多进程爬虫、多线程爬虫、异步爬虫、异步多进程爬虫,参数请参考文档
    ' m  ~1 H5 v& f, x7 y/ C' _:param url:即将请求的url地址,仅支持get请求0 Q+ h' D3 F5 ?2 m  w+ j4 ^0 `8 v
    :param type_url:请求url后返回格式,支持text和json格式返回
    3 K* N# D2 T! u, e8 j$ ?6 ~:param Thread_num:即将启动多线程个数,默认为1单线程- [6 R4 i/ y$ o* Z4 S
    :param sem:协程信号量,控制协程数,防止爬的过快,默认为5
    7 h6 B* r& Y, j% E% W8 m$ Z6 c. q/ ~:param cpu_count:运行爬虫使用多进程cpu核数,默认为系统核数一半
      g# Q$ E* D4 u- T: r, V8 a:param login:模拟网站登陆,保存登陆信息5 [% ]  i( E1 T. i
    :param Parsing:爬虫方式,支持re、xpath以及bs4方法4 f2 p! }2 I1 y2 h7 {/ S
    :param texting:是否启用连续爬虫,爬虫程序异常报错后重新启动爬虫,
    2 g6 Y: g: G9 T( l                       多次报错结束程序,默认否
    , z& V: g5 E! V1 h/ D$ u- ^:param label:选择器内容,字典格式保存,: n6 x# @! U& q  r" }# n- v% S
                         字典值为列表格式,第一个参数为选择器,第二个参数为转换类型  N# W7 f" M, `4 i1 n, q! q& W
                         第一个参数必填,第二个参数默认str类型
    3 S  A" u! M& P" L: V6 V/ B3 V% P:param write:是否写入文件,支持txt格式、csv格式、json格式以及pkl格式,默认否; v# r$ z* f5 d3 H9 @# \$ L
    :param next_url:是否跨页爬虫,选择器内容使爬虫继续翻页爬虫- i; L* A$ X% K1 g
    :param page:是否选择断续笔记接手下次爬虫处理,默认否
    1 j4 A3 k5 T, L; _  u:param clean:是否进行简单类型数据清洗,默认否
    1 }: ~; [5 g! q3 t+ A3 \6 Q$ t:param write_sql:是否写入数据库,默认否  L3 T* m: z, J$ [8 K
                             'host'默认为'localhost','post'默认'3306','user'默认'root',$ N0 J' p# O0 P3 i! M) s( R) }7 b
                             'password':'密码','db':'数据库','table':'数据表',
    2 N, x& c7 y0 y/ W* ^& r                         检测库是否存在,若不存在则创建,若存在则直接插入,) T3 [- Z3 q1 B( m) `& w0 K
                             检测表是否存在,若不存在则创建,若存在则直接插入! e8 D& U0 b0 G6 t- K. b" ]. t, u
    :return True3 d+ U: e, a* H; E& E* {6 x
    '''
    # U; A( q1 B* o9 F( B- J6 g介绍玩法/ W( V0 @' Z- k& |$ M
    接下来介绍的均为调用第三方库的情况下运行:
    2 C  x9 ]& Z# a: A
    / _* u" f0 N4 m. Cfrom simple_crawl import request
    4 H* i& p) a+ r3 @+ i9 e第一种玩法:输出源代码
    9 z+ t5 Q, H) i6 d+ n调用requests库进行源代码请求。
    / C: _8 Q  S4 w2 d0 V+ `( f1 c" y  \* N' U/ d/ S; d7 r
    特点:
    4 U# P& \  T/ Y3 n( n请求失败则调用ip池处理重新请求访问,% k" Q& O2 ]6 U
    出现五次失败默认网址输入错误。) M8 i  h% {$ J
    支持text以及json字符串返回。默认text。
    , ?# u3 Y2 h# a0 T; Q" [5 x
      [  R& H# [4 a2 Q" E缺点:' X( W& J6 a) k* s. w8 V$ Y, o
    暂时只能进行get请求,不支持post访问6 }) ^- f6 m7 e' \: r" N4 ?/ o$ P5 _
    # v6 I8 C7 L& E( |; _: r+ U" }
    :return text or json
    - l1 z4 r  C; B1 M6 _$ ]3 e/ d
    / {- @2 k; Q1 Q1 [" l' E* w1 mrequest.parse(; m7 B3 r& x* R' Z) B* p- c: k1 r
            url = "https://www.douban.com/group/explore",1 W" u+ ]: j3 n1 \# a7 U" C
            type_url = "text"5 H; @3 c2 P2 ?5 |" S: [
    ).run(); g! }3 m; l  o; I
    # return text
    & C* Q9 {  S) Y3 F% }) M8 U& t8 \$ c. K! H. ]2 E5 ]1 [/ G
    第二种玩法:模拟网站登陆并保存信息8 p  ^! ]9 A6 b4 K9 ?5 Z! N
    调用DecryptLogin库请求登陆访问。' c8 p0 @# J; Q2 j: L( r4 k. R+ [
    $ N2 G7 n6 I2 j6 ~; o
    ps:DecryptLogin库为大佬皮卡丘写的一个很不错的模拟网站登陆库,在此引用一下,因为单行爬虫原因不支持账号密码登陆,我将大佬写的二维码登陆使用过来了。再次感谢大佬开源
    $ k9 [; K, @9 y7 u" T在此放出文档地址
    0 O. M: s" A$ x9 ~0 qDecryptLogin库中文文档:https://httpsgithubcomcharlespikachudecryptlogin.readthedocs.io/zh/latest/
    9 O4 B2 m) f" ]3 Q! A; Y. }9 H, O9 y2 Y
    特点:7 ]. _% a( H6 E( ^/ h% q
    将DecryptLogin库中二维码继承到此库(非二次开发)
    & w( L  Q) L  V# F支持QQ群、QQ空间、QQ安全中心、淘宝、京东和斗鱼登陆(大佬登陆库中所有的二维码登陆), F* ?4 i0 s+ m! B1 z3 g  j
    保存session.pkl信息到本地方便下次登陆运行0 `* T) t2 B- M1 r" F# p4 w

    ' ^! m: F% O, v! ?1 t缺点:
    , ^" `4 W3 I& N6 M9 ssession.pkl登陆信息过时无法自动删除。& s1 w4 S) x  t& {. c
    导致下次登陆疑似cookie无法正常登陆。" C7 q, Y, O+ A: z8 b2 m

    - H, U% x. R# B  b! v$ \1 `8 o:return session
    * T! V& G% r/ ]6 S5 k+ R! q# z) O0 P4 n
    request.parse(' U2 C) @  S& A" \* h% I7 ?+ x
            # 臭不要脸的推广一下我的店铺
    $ T4 _" A+ c3 S        url="https://shop574805287.taobao.com/",/ {+ U, Z' u3 q
            login="taobao"" `+ S& A  q8 S0 D5 [5 P' l
    ).run()" a% D8 c" f) \0 m, ]) Z3 w! D
    # return text
    - g3 q- F6 Z4 s: |" q& v7 g1 R9 i: S3 }  c5 o4 K  K2 b" U! E
    第三种玩法:爬取网站信息+ s& n: n5 n6 J. h: g# u, Z6 S9 G
    爬虫库自然少不了爬虫的过程
    2 b) b' F3 F' C4 }9 [
    $ b* V( q% Q' F2 k特点:+ @7 ^. V0 ?5 t% n  X3 z  L! A
    支持re库,xpath解析以及bs4选择器。$ |8 f0 T  b4 o7 r( X0 ~1 _+ _
    爬取方法为字典格式。单方面输出。
    " F9 O$ K/ |& ^8 {字典键为保存的字段名称。
    1 j4 _( V3 p) W# L! d. [/ o字典值为列表格式:第一个参数为选择器,第二个参数为转换类型。第一个参数必填,第二个参数默认str类型。: M1 Q5 k( R& a" d
    : {6 t+ V9 E6 o  @/ {1 _+ K
    缺点:暂无(等待小伙伴们发现)
    " f) E' h1 F" V3 M  ]( ?2 v; r9 P8 b7 d! F6 }  d
    :return reptile_results
    * d# |% i: v- F0 Z0 v% J. w8 c" D% W  C
    request.parse(2 w9 [5 n0 u4 i! m( v9 E% i1 b+ |( F
            url='https://www.douban.com/group/explore',9 E6 d& i% d5 P9 m5 a
            # 字符串格式,选择器方法。
    ' w& U$ u8 O2 y8 P( m) d7 I    Parsing = 'xpath',
    8 U, F! w- x2 a) S% L) c3 J7 k) U    # 字典格式,参数如上。
      ^  n* l1 V, R/ z    label = {
    ) T  S% j$ e- P0 {; {, {% ]( A$ @        'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
    8 m. b& w7 P4 t. _+ J* l. t        'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],
    & d  C* M+ v# s! i9 h) E        'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
    % j' m; ]3 \7 C        }
    ( m7 t% ^* R4 A5 a9 _).run()
    2 P' C! g/ z4 A- y+ I1 A% z$ t0 n# return reptile_results(list)" p. F0 G% A  u( D2 ~# y
    ! K6 `0 L( ?4 F1 p; k7 I( ~$ b
    第四种玩法:自由保存信息. @; C( j" K$ n% H; U+ }: L* V- P
    目前版本支持保存txt、csv、json以及pkl四大主流文件。日后版本更新将发布更为全面的保存方法。' @2 w$ k' |$ C& O

    ! M2 F* K2 o7 `- A! K特点:
    % K8 t9 e- [2 v) e2 x+ d写入文件均为数据格式传入文件。$ ~9 C0 s: s  |' l4 V" j2 j, H
    且输入格式规范方便阅读and省事。
    2 l  s- O' p: N1 @/ T& r
    . _) I5 p9 c% v1 V缺点:- g; x- P8 @) a$ M. ]% t
    保存格式仅四种,  e0 J, {- V4 X. G
    不方便用户之后读写操作。
    + s/ I; z( C$ P. v6 ~' E, M0 e7 V) U) E
    :return file9 s3 v* n* z" n9 |7 u; j
    " l- }% b0 A4 e/ {( H" A8 h) }
    request.parse(! }' y* P" W0 b2 ^& ]! x
            url='https://www.douban.com/group/explore',/ ]! n6 C/ W) o, |. a! a
        Parsing = 'xpath',
    2 ~1 [: g0 y6 T3 ~7 N; d; o    label = {
    ) }# l$ c: N6 V( i, s        'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
    ! w, F5 w+ @& n3 y        'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],% u8 t- I2 j8 w4 f
            'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]. |- M+ I! s, E
            },0 {' C# c: ]6 N5 c( x# o- _% g: s* h$ T
        # 字符串格式,具体保存位置填写; J2 g7 r3 {- [) w
        write='result.pkl'$ M) L+ I2 \3 V0 @% V  b+ O
    ).run()
    1 f4 J( F( r; \1 M" w: Y6 [# return file
      d( E! d$ S# O. U5 J8 b
    ' ]5 E9 l2 N( v/ L9 q* u第五种玩法:读取下一页 url 地址继续爬虫
    , q- T% {& m8 j8 I$ R: T) F5 L这也是每个人都担心的问题,仅仅一行代码怎么可能翻页爬虫。这还真能做到哦~
    * N: H5 R+ r" e' k$ ?9 q+ _' i/ B, _  U3 C
    特点:7 {5 l0 p5 F+ s+ \; e! S' Y
    继承之前的Parsing参数选择器选择方法。! E2 \+ G6 Y' ~' E7 Q. S, \
    在这里可读取到解析后的下一页 url 网址。
    , [! N9 C$ y4 D7 ~方可继续进行爬虫处理。方便用户使用。
    ! t3 R$ h  D1 H- P1 [
    , o/ f2 \9 M2 M6 O缺点:7 m+ \% H/ b5 Y# w. v( x  s# u
    若爬虫时下一页 url 地址改变,便结束爬虫。
    $ P$ q  R+ f; s: ~1 }: O只能爬取所给 url 地址中的信息。
    ! a( D2 Z; R% D2 J: s8 m无法进行某一界面的多个网页爬取返回。
    7 T- y6 R) ~# @2 _造成访问页面单一流失。+ O9 u) H' L7 t8 @
    ' C& |7 _5 X) S) _3 D
    :return None% X' L( }, k6 S( o6 K2 s

    0 g0 `" l3 {1 \9 \# M4 `; X4 Urequest.parse(
    " }0 b! t' V% J( b% ~4 G        url='https://www.douban.com/group/explore',
    5 P) o( F! x8 \& I    Parsing = 'xpath',. ?8 U, t* n  m. D/ g( S
        label = {
    $ U' K: U; W& O- i        'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
    3 o- [( n+ B3 ]; u        'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],: }: g+ B! @1 m
            'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
    4 B- p3 p# Y) I* s* j        },
    " t8 v9 k, l6 g0 o4 q/ B/ I    write='result.pkl',5 [% |; l4 l" o
        # 字符串格式,根据Parsing方法继续请求下一页a中href( O+ U1 ~$ z. K% A: g" i1 Z1 h
        next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',
    7 L1 F5 A- j  F4 \$ v- ^" \).run()) n1 k, n$ K: r+ n
    # return None 3 a- c! N7 G; A9 H
    ; A' ~4 q9 b" F
    第六种玩法:爬虫网页保存
    ) \. a; U0 v; {听说过爬虫断续重连的朋友应该懂得这是个什么神仙操作。每次爬虫运行期间好好的,睡一觉醒来发现代码报错了。。。这就是个很难受的事,还不知道之前爬取到哪一页了,只能重新爬虫了啊!
    0 R" m$ A2 R0 e) g6 h+ z+ v2 \" v: d( J  o- _
    特点:
    ' W7 {3 q# ~  t* ?持续输出断续笔记。' ^0 N1 N6 X# E! t/ }. Y
    将此次爬虫的 url 地址保存到一个文本文档内部。8 [/ H; j+ W6 s* }3 S; c+ z
    下次读取文本文档即可快速进行直接断掉的爬虫 url 地址继续爬取所需。
    & b5 H4 p& T0 ]3 k1 `+ j, [3 B
    ( v, d" K0 \1 F0 [, s7 T# f# X* Y缺点:4 Q9 z% T2 J" _0 ]
    读取内容不单一。( @( B  [5 o# D: w
    导致下次爬虫无法正确读取上次爬虫留下的痕迹。2 H( H6 V+ [; Y$ }
    3 b6 P  _" }) ]. [( }. H
    :return url_file
    / M! e: E5 z$ r% A1 g7 A2 c- U1 K, K1 S5 y
    request.parse(9 Q7 F0 R2 J! k# d+ ~# m( ]5 |: F
        url='https://www.douban.com/group/explore',
    . p6 u  P7 n6 c- F  B* M5 |    type_url='text',' O/ v3 s2 E# K0 x) }9 R7 a- z
        #login='taobao',6 r  J  p# g# |6 t
        Parsing = 'xpath',
    ; T1 o- x7 b, T  P* \. m- R    label = {
    0 X( v/ v2 T+ L7 U9 |6 n1 o$ u        'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],* r4 W& |1 r/ G3 U3 n* s5 o( T( g
            'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],
    8 ?1 T) a6 t# P0 s& ~2 A        'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]4 a- M  T2 O% H7 D
            },
    2 X  p9 j$ b9 ]. R1 K3 D4 Q4 ~    write='result.pkl',
      M, ]. J1 [8 C+ u7 c% |- L9 }/ R    next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',
    ' |3 {- T2 \* R' C    # 第一个参数为是否需要断续笔记。
    ! }8 O+ W& v- Z! l# R    # 第二个参数为断续笔记保存位置。
    . b- O$ F5 V$ H8 L    page=[True,'url_page.txt']
    * A* C1 i) c% `, w! z9 |' Q).run()
    3 \; u: N9 k7 B7 a! G  Z" c9 A# return url_file0 k$ g/ g/ }  D3 X0 C

    ( b) r9 C% \$ `) U! D5 y1 o第七种玩法:简单数据清洗; V) E3 B. n$ v" T; x& P
    数据拿下后,直接保存到本地有些大佬可能觉得很辣鸡,连清洗都不清洗就存入本地了?那得拿到多少废数据脏数据。那么接下来介绍一下清洗参数。
    : a0 w0 s8 L; l- V8 _% k
    ! h0 T: r/ h  s# M# ~) {' Y6 u特点:
    ; i/ A" `6 ~8 u& }/ K+ R本人曾写过一个底层数据清洗。
    $ U/ L# o" f3 T% A1 M能将列表格式数据进行归分清洗。6 Y) ~7 `+ A) p% D
    主要内容请参考另一篇文章
    1 S- @" v+ R" m1 L" B如下连接:数据清洗
    2 g7 Z- g& q0 v& e8 t$ t& t1 }1 d6 E! R& U. S) _: u. H; a
    缺点:; `7 L% D" x  R4 Q) B
    数据清洗格式简单。; }8 p( N' Z$ \
    数据清洗内容单一。
    2 a8 R/ }& Z3 v4 A4 O无法完全做到绝对清洗。) `( m/ f6 f- t: X# y# O) \
    有待改善。
    ' x1 L+ X6 `+ S4 g. z6 B' a4 @2 u$ a" i8 U' N% e- S  W
    :return keyword_list, value_list+ I- a. ~& ?5 N9 a" ]

    ( D9 |( J" ?# E8 v/ W) z' ^- X7 j( ~request.parse(" A/ R3 B- Y$ }% B4 _; H
        url='https://www.douban.com/group/explore',, L* B8 ]; B$ Q# J4 e. }5 E
        Parsing = 'xpath',1 i3 }/ x3 D# ^( O
        label = {
    9 e3 w3 Y0 G, `1 T$ ]4 ^( @7 q  G        'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],- O/ ^/ c  A( F  P9 L
            'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],! A0 O) G7 ~. T
            'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
      u0 [* T+ u# B# y7 u        },0 w8 h2 |9 C9 X
        write='result.pkl',3 p' t/ q) |" S
        next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',, c3 A, r/ n- i6 D/ s9 Q
        page=[True,'url_page.txt'],: p& B& q! e( W: R1 k4 n- I
        # bool类型,默认不清洗* Z0 P& [$ s( p. f
        clean=True
    , n9 m( B5 R7 s' O).run()
    ( h1 q  N  ~0 h6 J( C) _3 ^/ a0 V( @! V# C
    第八种玩法:爬虫存入数据库* h! _; X3 {7 ]# a& B* @9 ~
    存到txt、存到csv、存到json、存到pkl,那也太low了吧。现在流行的数据库用不了么?那是不可能的。。7 M" U7 K1 b0 V! u. F

    ! v) `2 ^& ~/ o- F% Q' o特点:: B% C5 y/ ]' {* `: `6 p* u/ @
    信息存入MySQL数据库。
    8 {$ w  M; A4 M7 ~可连接docker远程数据库。
    # [$ k, ]! z: [. F+ u: W7 a数据库的库名可以不存在。% }% s: `% s; S2 Y1 V$ R
    数据库的表名可以不存在。
    , X4 [' V/ B7 W. P+ W根据之前传入字典键与值参数判断表类型。
    2 z+ b: t7 T8 P8 \6 |: i$ z, k1 q自由建立数据表传入信息。
    , p. _+ b8 w6 Y, M' k0 H. T: q. k' z" K% N$ I+ w
    缺点:- H+ u# d1 _# i8 q! k
    仅支持MySQL数据库。9 C. R/ }$ V! \. A  j5 l8 Z* @7 o

    ) x( ?0 S& V. \5 J5 Y% W- e) u:return SQL
    ) r+ ^- w0 m0 j7 G! d
    ( `0 H( R  p8 U8 X- Prequest.parse(/ c# j+ U; F! h, r3 U2 m
        url='https://www.douban.com/group/explore',' s7 @$ }( I& N9 f+ U9 n8 Z/ r7 o7 @5 N. X
        Parsing = 'xpath',0 @6 m  G0 t( i" a
        label = {2 I9 [6 \' p) z" U& w( o
            'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],' c/ I/ t; W6 b' K
            'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],& v6 y7 R2 ^& S3 m0 l- g; Y
            'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
    ' m. O. l7 w3 r( a6 y        },4 E9 E! I# \, g  Q
        write='result.pkl',4 n8 ~# O( E, M' g1 n% T' @( L" u
        next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',$ K# b8 g3 A6 T! E
        page=[True,'url_page.txt'],# y1 ?, }/ ?- _* p$ H% [; F$ ]
        clean=True,& l( ^9 Z& Q" E6 j
        # 字典格式,% Y$ ]5 S9 k$ {7 O% i
        # host可有可无,默认localhost* e0 Q5 @7 Z+ Z, P5 [' g
        # post可有可无,默认33063 N3 M% A. t+ `2 I( i
        # user可有可无,默认root2 D) h. V+ D$ A, o, d# u
        # password必要参数,数据库连接密码
    ) F8 U4 {4 |& A    # db必要参数,数据库即将存入的库名
    4 [4 _9 ]7 v, K* Q% J0 u    # table必要参数,数据库即将存入的表名% H5 d6 ~( P  \9 ]5 B8 D3 o
        write_SQL={! L; o0 h: n/ ^7 C5 G( ^
            'host':'localhost',4 N- h" b' J0 L- `# y5 @" |' j0 D" [
            'post':'3306',. f0 i$ x% W4 }' m. J' [1 `0 O/ w4 z' D
            'user':'root',
    . A+ h! p0 f" G) ?        'password':'123456',6 B' g; W3 @0 v0 T! @
            'db':'example',0 Z5 ^" i( _! e3 p- M
            'table':'example'5 k1 u- G" [. g' t+ {( Q' K$ [- j3 G( I
            }
    5 o2 E/ i$ D' Z# u4 [  _    ).run()8 o1 |2 R1 h- y( }

    ) c3 d; ~0 W' z! a第九种玩法:重新启动爬虫+ O- X( E8 u& ]1 i( B3 B
    爬虫最让人厌烦的就是被一个不痛不痒的错误信息给终止爬虫了,比如意外的远程断开链接等低级非代码错误,报错之后还得重新启动断续爬虫,就显得很麻烦。我做了一期爬虫程序异常报错后重新启动爬虫,多次报错结束程序。
    6 S$ E/ N4 }5 G! w
    % ~; w% `' v' X2 K( Z9 q特点:$ o5 u- k+ L% Q+ u# q5 D4 S
    检测报错重新启动爬虫
    ( ]$ E  a0 c* \% S8 V9 h% D# q无需手动处理错误信息
    ( H5 A  M+ x7 o' N, t+ }( ~: H! a7 r) S" M) X* J: J. T
    缺点:
    & g5 k/ r2 I; p9 y# T2 s+ Z无法收集子线程错误。
    + r: ]7 W/ B! W8 c& Q9 u& V; f0 R: X5 H% _. D
    :return None, f+ r! Z% B; J6 f% }

    + _. ]  x$ e- l$ p9 orequest.parse(7 r" I. E& _) \7 ^* C/ n1 \
            url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],
    - |) }$ D& }3 k        #login="taobao",
    : w( J' ?  ?: P0 m3 |. F- ^        type_url = "text",
    ( p7 f- ~% V( L% D        Parsing = 'xpath',
    ) o' \2 D- H( u0 ~' E        label = {
    3 s% x* r0 T9 m6 Y7 s3 C: ?            'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],6 B( q5 j( o# k% D4 f5 ^$ S
                'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],7 r) s- }- `( \* X8 F8 }! K
                'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]  O5 O. z8 U( d) ]/ d
                },
    $ a0 N4 z$ R/ I        write='result.txt',* J/ t! i8 ~+ n, B) G
            next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',5 f4 l+ ?. v  O; `1 O5 b. D
            page=[True,"now_url.txt"],
    - U6 y; c3 P0 ?; g/ p4 r        # texting 参数为是否启用连续爬虫
    % u8 l- l" t& M5 o) K( ^        # 爬虫程序异常报错后重新启动爬虫! j  c7 w0 V7 H2 e1 H8 J. M, A
            texting=True,
    8 {% w+ r5 W- r5 X: }        ###+ V" m- ~  q+ ?$ f" T$ p# c7 D9 D: I
            write_SQL={1 t4 U) ]' f0 F) R
                'host':'localhost',( r3 q. r  }/ C% n4 r3 M
                'post':'3306',
    0 c2 X' G3 B* y- }            'user':'root',, T8 b. f+ c1 m3 {
                'password':'123456',
    ( c" ^# }* U' r0 e3 G4 W4 N4 y            'db':'example',- d( h% F) o0 b2 t
                'table':'example'
    / f8 i( ^0 ?5 x3 n' ?. N            }
    ! y; S: v4 P8 D! _! P* p& R).run()# V- z, X, X. i1 w3 K% N2 C# E8 M

    6 g' c1 [8 ]. C3 v2 T第十种玩法:多线程爬虫, x/ y# G' J7 i5 C$ ?
    特点:
    4 N; M7 w3 m9 _' }爬虫速度加快,- g# R: ?6 u3 B
    更好的利用了线程。' W# x, k* U" ?* j* |$ |. i

    ; ?0 R  L$ H0 G) v/ ~' y( m/ ?0 d缺点:暂无( e8 ~8 h9 |# v' a9 I0 l' f

    4 R  L8 M9 u  k3 T: `  x9 {:return None
    $ A/ {- r& ]4 v4 |
    . A$ Q& m& t: t* a$ Srequest.parse(4 k$ S# N$ b: |* l& P
            url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],
    ' k  [# Q$ @; S8 \. f' T) i        #login="taobao",
    6 k0 W+ D9 \, i% c        type_url = "text",: d: {/ C, _2 ~5 }! t5 [& K
            Parsing = 'xpath',8 m% c4 e2 z2 d* {: Y3 ^
            label = {
    7 q9 w2 M9 a! f- n( t7 l4 V% q$ g            'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
    7 @9 K$ h) f  f; H" y, E& I# y, T            'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],* \% S! J# N3 d  M: _- G
                'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
    7 n9 ?$ b  [8 i8 _2 s# v, [7 L            },
    - s4 D/ {* w8 y( f; ]% h        write='result.txt',
    ; j5 Y- O3 V1 U# w        next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',+ a. @6 A1 j& G3 v; A
            page=[True,"now_url.txt"],
    7 W- j# y6 ], U, u        #clean=True,# K$ b% E; X- [+ s
            texting=True,
    + o' w9 w+ C" W7 N) M: ^        # status="threads" 启用多线程爬虫
    8 w* j* I+ \) w4 V+ r        # Thread_num 为线程数目,默认为1 单线程) M/ e1 G- W( }9 a$ z
            status="threads",
    8 v, R* ~( d9 }% j# K2 W- U        Thread_num=3,
    ; [; w$ E) ?7 a1 X! W0 h        ###
    ) T# P  W* `' |! Z9 e& u6 Q- n        write_SQL={! ^8 m# Z* ], d) }% u$ M  B
                'host':'localhost'," y# N9 e2 }( ~( A, Y6 ?
                'post':'3306',
    9 B) u" o' c4 v4 g) E            'user':'root',
    7 F3 E' a3 p3 }# S, T. `            'password':'123456',3 }& |% U6 l: i# P. E2 s  H
                'db':'example',
    # }% g5 T9 T* E7 \6 X  H            'table':'example'
    2 ~" u$ K  J; k$ _            }
    ' s+ H/ G- [( A" a0 F).run()
    / `. q+ d# o4 N+ K! D- @/ s9 Y& a& G! j" a% h* ~6 f8 v$ F4 [9 J
    第十一种玩法:多进程爬虫
    1 M0 s( M! s: [7 M2 i  K特点:, O, V8 R$ Z. l; l) r
    爬虫速度加快,
    3 D+ m* }; }; K, |  E9 T; I; r  f更好的利用了进程。1 K1 x$ s% Y; R& j2 S8 s, M

    ; i, P$ _4 M8 r! b9 l& o4 M% q* N6 y8 [# W缺点:暂无) I( n1 Q" }& H* Y" @

    % g+ p: Q4 Z' M& ^1 x( @5 W2 f:return None
    6 D& ^) _2 f6 @( F3 R: G, @' P. j* z' [) k
    from simple_crawl import request
    % V+ `, v* k$ @' a" {. y6 N2 c' Yrequest.parse(
    " K, t0 D3 p" R! X9 z$ X        url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],
    , X$ \( [5 J. Z9 A' E        #login="taobao",
    ( ~5 ]; u6 E$ f' a4 w        type_url = "text",
    " X: M! F- p, d        Parsing = 'xpath',
    6 u/ [2 y! i' g# g+ c4 k7 }        label = {
    # p; F  g8 M. p$ s            'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
    4 z( X2 X6 @% ]8 ^& b1 q            'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],
    % ?4 a8 d3 G6 w; Y$ f6 I            'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]/ q" S. |& H" t8 D
                },
    9 W2 W  n8 Z. l4 e: @        write='result.txt',
    ; [4 |8 h+ j/ e7 F2 t) h        next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',
    3 l" E3 T- K" Y/ u        page=[True,"now_url.txt"],
    ! i: H3 p3 N0 R  f        #clean=True,
    4 L/ r- v& U* g4 H( o$ A2 Z        texting=True,
    $ p; O% \4 i" T- S' \" s        # status="multiprocessing" 启用多进程爬虫
    + Q( J+ H# L& W0 Z        # cpu_count 为启动代码核心数,默认为系统核数一半8 Q& w. g8 s7 F! y
            status="multiprocessing",2 f, a: ]6 ^( g: r' {4 D
            cpu_count=2,5 y" K; f; K1 S! P
            ###
    . M2 @( W% m% \8 u1 _  M7 D4 J. M1 [        write_SQL={; T& ]: T% v0 y" V+ ?# H. R
                'host':'localhost',$ O) D+ [8 a, I* U; O4 _) Y- a
                'post':'3306',
    : M+ T9 |7 V# o5 ~' e6 P6 n: m            'user':'root',; Z- t! n6 w; Q3 A% l
                'password':'123456',
    * P! S2 R" j" Y+ L2 v, b# R* K5 G            'db':'example',
    3 t* W! I5 ~' a3 n( u4 W. {            'table':'example'
    4 g' _7 N2 I0 w; ~3 g! k. M            }
    0 V1 U' J9 `, H6 l+ s).run()0 o4 J8 r5 p! O6 H) b
      ~7 {( o( h) {& v! v0 N5 C
    第十二种玩法:异步多线程爬虫0 @+ _+ R8 _/ m  ?
    特点:
      I6 }% `: n+ ~" `3 C8 P; f5 t( [: L爬虫速度加快,
    2 U4 d) ~7 X! i' `异步使得爬虫无等待时间,' Q2 ?* b0 s$ X% N# x: R
    同时使用多线程速度明显加快。
    - W+ F/ H. {) |, R8 R. _$ l$ c5 h  T5 Z# K0 U7 p5 M* c0 Y
    缺点:暂无: _& e4 L! e- d. n3 f; X$ H; B7 Z

    , X9 v% [3 q3 P) l" q:return None
    . E4 q: s* Y+ x6 \* {# }& a
    # U2 g+ x0 \% L6 I9 {4 F% _from simple_crawl import request  C9 M1 A: b$ C8 Q6 x! Q; ?" J: T7 l
    request.parse(& ]3 [0 G1 a) J8 N/ p
            url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],' A: S0 \/ X  M8 z" I  k* J2 u6 K
            #login="taobao",( t0 J2 Q1 E; P5 d9 n2 A# b9 @
            type_url = "text",
    2 X# g) A  }5 P5 h' Z- _        Parsing = 'xpath',
    6 \7 z7 o7 K5 t( o        label = {# n9 G8 t4 M/ t: _& I4 ^
                'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],
      c; H6 z9 k1 A- f1 E            'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],8 l4 x' [0 |- \& q0 H3 E7 {* Y
                'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
    6 |4 Q. H* m* T/ _$ Q            },# {3 |" b# P1 f7 P  w5 T( E# ?
            write='result.txt',
    ; I' h# t9 [* j. B, v+ C* @4 F4 z3 I. v        next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',
    / O7 j& X) w( [- @5 L9 J        page=[True,"now_url.txt"],+ w2 ]. S9 `8 r
            #clean=True,! F% P$ O+ a. q: g2 S) Y
            texting=True,1 `$ M0 ^% d" i- |
            # sem 参数为异步引擎数目,默认为5
      u9 x5 R* Y) ?# F: I" g        # 其他参数同上  ?* v+ S" _8 e0 V6 A) {0 Q8 ?0 Y
            status="aiohttp",
    ; h5 z" C, O$ t- P) V" \        Thread_num=3,6 u5 c- @* N$ h6 n
            sem=5,1 w1 a, q0 F0 q# B- d. D
            ###
    4 ^( F/ F, D' P) Z& C( E! w        write_SQL={
    0 R: b7 G' ?) M" _            'host':'localhost',
    - k2 k- I- U; v' V* n  B            'post':'3306',
    ) t8 @/ p( ~! k$ b" o) o            'user':'root',
    , g" ~2 o# t2 A' p, W! F            'password':'123456',
    ' F5 e6 g& q& k* w            'db':'example',2 q% l. X, y: s3 p+ E! S+ ~0 s: [
                'table':'example'
    " Z& b" m# j  t( @1 M            }
    : R8 H2 R. P9 ~% K7 N0 n" K# D).run()
    + A3 m8 Z7 [! |: `+ s% i2 N/ s
    , s( l% R' }# _& F* q! D; I+ u# z第十三种玩法:异步多进程爬虫
    ' i" {4 m3 g$ ]! f8 o  R特点:, L- H1 }9 t' J% ^5 E
    爬虫速度加快,7 B% U) A# k/ }% ?8 {! C
    异步使得爬虫无等待时间,1 [& ~9 N5 b  _  q+ `
    同时使用多进程速度明显加快。) ?2 A+ X2 m  m9 \: Q7 p; n! W
    3 I3 Q+ P$ \' P( w0 ?% |+ n
    缺点:暂无8 E0 P" T: n7 H$ d
    9 s% m, }! g' |% o0 T) t. O
    :return None
    1 e$ j. r. [3 W5 W2 [# [& U& @* J
    / V" \* @& X+ W+ Q: ?; V: {from simple_crawl import request2 b& M1 p1 i1 y/ x9 ^
    request.parse(: t" T& D  J3 g0 I& F" ?7 {
            url=['https://www.douban.com/group/explore?start={}'.format(i) for i in range(0,180,30)],
    2 ?9 T2 e9 K, r9 C# ^2 Y        #login="taobao",! u6 C$ R. W8 A, l8 v1 R* v
            type_url = "text",3 n8 z5 w, k& H4 c  u
            Parsing = 'xpath',$ j) G" s5 l2 o( a$ P, l
            label = {; y- }, c# G! t2 C3 k" d8 g- y6 u
                'url':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/@href',str],% ]1 p+ _  O/ r
                'name':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/h3/a/text()',str],8 _, g/ W) `7 I4 @( N  Z  f3 b
                'Author':['//*[@id="content"]/div/div[1]/div[1]/div[1]/div[2]/div[2]/span[1]/a/text()',str]
    ; \0 b) L0 p4 ~            },
    8 T% n4 v( E6 c- b/ _, `) G# c: e        write='result.txt',/ U0 v5 i& j, |3 _5 t
            next_url='//*[@id="content"]/div/div[1]/div[2]/span[4]/a/@href',
    : V4 R4 H- G. p        page=[True,"now_url.txt"],
    % i( E. E9 B  A4 k0 x# [0 _7 _        #clean=True,2 W% O- T: g' o# s. p( F; q
            texting=True,
    # N% Z: F9 P  F0 T6 [        # 参数如上
    " |6 B8 z1 ^+ z        status="between",
    - Q" ^" f- e6 S) e        cpu_count=1,% O! w; W$ V" h$ N7 Z# {
            sem=5,
    # }$ x5 G$ F& A        ###+ D/ B, U' l' Q( y% u
            write_SQL={
    " p* S, M5 e' v' H% R            'host':'localhost',
    3 P; p% l* d9 ?+ g$ C            'post':'3306',
    $ w+ [- x' _5 X) f9 B5 O9 D            'user':'root',
    " b1 c# U; N4 z            'password':'123456',' R) Z' v; U0 a# \0 g2 J9 K
                'db':'example',$ Y0 t7 l+ x4 K; q1 m
                'table':'example') l' f  k- z7 [. \6 o
                }
    1 P2 J# I2 s4 d8 c).run()! m: A4 a9 i5 }+ F2 _# F( A- B
    ' ]2 R  r; d' Q9 a: N2 }$ A# ^

    7 s7 I- P2 E: D( m) |功能介绍完毕🤞
    0 |% C0 H+ ^+ _1 F最后还是希望你们能给我点一波小小的关注。8 U# Z) |% t9 Q; U, `
    奉上自己诚挚的爱心💖$ O7 B2 R, F' N& g0 ?
    ————————————————9 c3 h3 ]; B) @/ f5 G# j$ Z) w
    版权声明:本文为CSDN博主「꧁༺北海以北的等待༻꧂」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    # U! N* A) W, H. I& [$ \$ u1 Y原文链接:https://blog.csdn.net/qq_45414559/article/details/106005684
    8 y, _( ?# a* }1 l! P+ F
    + Y& Y3 o! u  u0 s
    0 M1 @! T+ Y$ \$ f
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    738391227        

    0

    主题

    6

    听众

    32

    积分

    升级  28.42%

  • TA的每日心情

    2022-2-20 17:52
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    自我介绍
    哈哈哈哈
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-6-22 14:57 , Processed in 0.321862 second(s), 56 queries .

    回顶部