V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
yangzhezjgs
V2EX  ›  Python

请教 V 友一个爬虫相关的问题

  •  
  •   yangzhezjgs · 2018-03-21 14:49:10 +08:00 · 7211 次点击
    这是一个创建于 2458 天前的主题,其中的信息可能已经有所发展或是发生改变。
    药监局网站
    http://app2.sfda.gov.cn/datasearchp/gzcxSearch.do?formRender=cx&page=1

    有需求需要从药监局网站抓取一点数据,发现药监局网站反爬虫无法破解(返回 202,无法抓到正确的 html),想求教一下各位大佬有没有解决办法?

    已经尝试过的方法:
    1.requests + fake_useragent
    2.PhantomJS + selenium
    3.requests_html 的 render() (pyppeteer+Chromium)
    第 1 条附言  ·  2018-03-21 18:04:40 +08:00
    应该可以结贴了
    @manzhiyo @brightguo @goofool
    感谢几位,总结如下:

    from selenium import webdriver

    url = "http://app2.sfda.gov.cn/datasearchp/gzcxSearch.do?formRender=cx&page=1"
    driver = webdriver.Chrome()
    driver.get(url)
    print driver.page_source

    chrome 默认配置可以
    headless chrome 可以
    phantomjs 默认配置不行
    23 条回复    2018-03-21 18:07:16 +08:00
    scriptB0y
        1
    scriptB0y  
       2018-03-21 15:07:09 +08:00   ❤️ 1
    你要弄清反爬的点在哪里,哪个 header 是必须的,不然你换来换去什么都没用
    yangzhezjgs
        2
    yangzhezjgs  
    OP
       2018-03-21 15:19:31 +08:00
    @scriptB0y 感谢回复。。问题是我就没弄明白他反爬的机制是什么。。。返回状态码 202 我还是第一次遇到
    scriptB0y
        3
    scriptB0y  
       2018-03-21 15:45:26 +08:00
    @yangzhezjgs HTTP 状态码一般都没有什么意义,有的返回给你 200,但实际上页面没有内容,这取决于具体网站的实现,没什么太大意义。

    你需要模拟出来这个 HTTP 请求,然后测试一下不加什么 header 会被阻止,你就知道哪个 header 是必须的了。然后你看看怎么在代码中获得这个 header 的
    yangzhezjgs
        4
    yangzhezjgs  
    OP
       2018-03-21 15:57:54 +08:00
    @scriptB0y 老哥,问题在于他并不是根据请求 header 来做判断,而是他是中间通过 js 做了一次或者多次跳转,而不是简单的通过一次请求的 header 来判断。
    返回的 202 只是一个中间状态,之后还有跳转,最后还是返回 200,但是中间这个过程我找不到办法模拟
    manzhiyong
        5
    manzhiyong  
       2018-03-21 16:06:28 +08:00
    用 webdriver 调 chrome 试试
    yangzhezjgs
        6
    yangzhezjgs  
    OP
       2018-03-21 16:14:05 +08:00
    @manzhiyong 理论上来说 Pyppeteer 就是调用 chrome/chromium
    https://github.com/miyakogi/pyppeteer
    opengps
        7
    opengps  
       2018-03-21 16:37:48 +08:00
    ua,reffer 完全按照浏览器里的填写
    scriptB0y
        8
    scriptB0y  
       2018-03-21 16:52:02 +08:00
    @yangzhezjgs 你先拿到 202 这个状态的结果,后一个跳转的目的地肯定是通过这个结果计算出来的吧,然后如果再跳转那你就继续看看,我遇到过的情况一般都这种 js 都可以模拟出来的。 除非某个地方的 js 通过加密计算需要一个 token,那就只能用浏览器执行这段 js 了。
    yangzhezjgs
        9
    yangzhezjgs  
    OP
       2018-03-21 16:52:55 +08:00
    @opengps 这种方法我之前尝试过了。。。并没有用
    yangzhezjgs
        10
    yangzhezjgs  
    OP
       2018-03-21 16:56:56 +08:00
    @scriptB0y 这个我也想过,但是他做了加密,202 的返回结果类似乱码,并不是真实的 js 代码....我 copy 下来保存为 html,在浏览器里打开也是空白....
    brightguo
        11
    brightguo  
       2018-03-21 17:16:13 +08:00
    我来爬爬爬看,验证下你说的方法~~~稍等
    yangzhezjgs
        12
    yangzhezjgs  
    OP
       2018-03-21 17:18:52 +08:00
    @brightguo 欢迎欢迎。。跪求解决方法
    manzhiyong
        13
    manzhiyong  
       2018-03-21 17:35:10 +08:00   ❤️ 1
    from selenium import webdriver

    url = "http://app2.sfda.gov.cn/datasearchp/gzcxSearch.do?formRender=cx&page=1"
    driver = webdriver.Chrome()
    driver.get(url)
    print driver.page_source

    我这是正常的
    brightguo
        14
    brightguo  
       2018-03-21 17:40:12 +08:00   ❤️ 1
    +1

    driver = webdriver.Chrome()
    driver.get(url)
    html = driver.page_source

    可以
    yangzhezjgs
        15
    yangzhezjgs  
    OP
       2018-03-21 17:42:04 +08:00
    @brightguo
    @manzhiyong
    等我试试。。。没试过用 chrome
    Arrowing
        16
    Arrowing  
       2018-03-21 17:45:00 +08:00 via Android
    会不会掉蜜罐里了?
    goofool
        17
    goofool  
       2018-03-21 17:49:20 +08:00   ❤️ 1
    chrome 默认配置可以
    headless chrome 可以
    phantomjs 默认配置不行
    Itoktsnhc
        18
    Itoktsnhc  
       2018-03-21 17:56:46 +08:00
    目测是 cookie 的关系:
    Cookie: JSESSIONID=C340BCBB36485013122B70B59E0B6A8A; FSSBBIl1UgzbN7N80S=GbBGB7f4oP98rH7eXqhUFWb8PraboCvvQXAinlgIcUXhi7Ov2KSFc0dWQz_zW6ah; FSSBBIl1UgzbN7N80T=1kZkIyFDq0P301zKjNjN0vzCd1x2Dk7s7khgO0Pl3eB0QvuYIgJ8M08UKApGxZHudaZwJMb.oTpIxWG5pgLxfaiAFvaj3JvQS1e.HYuPUEEHpzHfnSv0BvoKMQ50_EGSRlq9Ckj7r8dA0zybuc_CocLCuY20VgueYiHnURhsgHb0e5UDm3MevKP37CZ1iHRrtkkt2RFnMrduBwI7Uywge3hlRVIwAT9JVcBDg0FrMR0gF4_eHR1IW47QcUEDiZ4HyKNAQ.BqyRZH1W6dLcrqIZhWyyzIXkH_Ts4QmZ_EcCgXwR.DiSLxAxY9T8AyxDhiqB3Rk5HttJgOukIvAMJi.svxT1Y01dPJex0nAMyn7rivliq
    xlrtx
        19
    xlrtx  
       2018-03-21 17:57:01 +08:00
    如果有时间可以看下他的交互协议是怎样工作的, 推荐一个视频和播主, 他的逆向 JS 的思路很不错, 用到了函数 hook 很有意思.
    Itoktsnhc
        20
    Itoktsnhc  
       2018-03-21 17:58:12 +08:00
    以及当 202 的时候返回响应里面:
    Itoktsnhc
        21
    Itoktsnhc  
       2018-03-21 18:00:45 +08:00
    不好一次 ctrl +enter 手误 提交了
    接上条
    <script type="text/javascript">window.onload=function(){var _$rU=document.getElementById(_$f7('ondoal'));_$cc(_$rU.name,_$tY(_$rU,_$zo('mdpf2UXqQG')));};</script>
    看起来是写入了 Cookie ?
    同时返回的 html 中有个<meta>
    benzzz
        23
    benzzz  
       2018-03-21 18:07:16 +08:00 via iPhone
    @xlrtx 方便贴个链接吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1049 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 18:31 · PVG 02:31 · LAX 10:31 · JFK 13:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.