操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    用Python開(kāi)發(fā)爬蟲(chóng)是一件很輕松愉悅的事情,因?yàn)槠湎嚓P(guān)庫(kù)較多,而且使用方便,短短十幾行代碼就可以完成一個(gè)爬蟲(chóng)的開(kāi)發(fā);
    但是,在應(yīng)對(duì)具有反爬措施的網(wǎng)站,使用js動(dòng)態(tài)加載的網(wǎng)站,App采集的時(shí)候就得動(dòng)動(dòng)腦子了;并且在開(kāi)發(fā)分布式爬蟲(chóng),高性能爬蟲(chóng)的時(shí)候更得用心設(shè)計(jì)。

    Python開(kāi)發(fā)爬蟲(chóng)常用的工具總結(jié)

    1. reqeusts:Python HTTP網(wǎng)絡(luò)請(qǐng)求庫(kù);
    2. pyquery: Python HTML DOM結(jié)構(gòu)解析庫(kù),采用類似JQuery的語(yǔ)法;
    3. BeautifulSoup:python HTML以及XML結(jié)構(gòu)解析;
    4. selenium:Python自動(dòng)化測(cè)試框架,可以用于爬蟲(chóng);
    5. phantomjs:無(wú)頭瀏覽器,可以配合selenium獲取js動(dòng)態(tài)加載的內(nèi)容;
    6. re:python內(nèi)建正則表達(dá)式模塊;
    7. fiddler:抓包工具,原理就是是一個(gè)代理服務(wù)器,可以抓取手機(jī)包;
    8. anyproxy:代理服務(wù)器,可以自己撰寫(xiě)rule截取request或者response,通常用于客戶端采集;
    9. celery:Python分布式計(jì)算框架,可用于開(kāi)發(fā)分布式爬蟲(chóng);
    10. gevent:Python基于協(xié)程的網(wǎng)絡(luò)庫(kù),可用于開(kāi)發(fā)高性能爬蟲(chóng)
    11. grequests:異步requests
    12. aiohttp:異步http client/server框架
    13. asyncio:python內(nèi)建異步io,事件循環(huán)庫(kù)
    14. uvloop:一個(gè)非??焖俚氖录h(huán)庫(kù),配合asyncio效率極高
    15. concurrent:Python內(nèi)建用于并發(fā)任務(wù)執(zhí)行的擴(kuò)展
    16. scrapy:python 爬蟲(chóng)框架;
    17. Splash:一個(gè)JavaScript渲染服務(wù),相當(dāng)于一個(gè)輕量級(jí)的瀏覽器,配合lua腳本通過(guò)他的http API 解析頁(yè)面;
    18. Splinter:開(kāi)源自動(dòng)化Python web測(cè)試工具
    19. pyspider:Python爬蟲(chóng)系統(tǒng)

    網(wǎng)頁(yè)抓取思路

      1. 數(shù)據(jù)是否可以直接從HTML中獲取?數(shù)據(jù)直接嵌套在頁(yè)面的HTML結(jié)構(gòu)中;
      2. 數(shù)據(jù)是否使用JS動(dòng)態(tài)渲染到頁(yè)面中的?數(shù)據(jù)嵌套在js代碼中,然后采用js加載到頁(yè)面或者采用ajax渲染;
      3. 獲取的頁(yè)面使用是否需要認(rèn)證?需要登錄后頁(yè)面才可以訪問(wèn);
      4. 數(shù)據(jù)是否直接可以通過(guò)API得到?有些數(shù)據(jù)是可以直接通過(guò)api獲取到,省去解析HTML的麻煩,大多數(shù)API都是以JSON格式返回?cái)?shù)據(jù);
      5. 來(lái)自客戶端的數(shù)據(jù)如何采集?例如:微信APP和微信客戶端

    如何應(yīng)對(duì)反爬

    1. 不要太過(guò)分,控制爬蟲(chóng)的速率,別把人家整垮了,那就兩敗俱傷了;
    2. 使用代理隱藏真實(shí)IP,并且實(shí)現(xiàn)反爬;
    3. 讓爬蟲(chóng)看起來(lái)像人類用戶,選擇性滴設(shè)置以下HTTP頭部:Host:https://www.baidu.comConnection:keep-aliveAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36Referer: http://s.weibo.com/user/gamelife1314&Refer=indexAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.8
    4. 查看網(wǎng)站的cookie,在某些情況下,請(qǐng)求需要添加cookie用于通過(guò)服務(wù)端的一些校驗(yàn);

    案例說(shuō)明

    靜態(tài)頁(yè)面解析(獲取微信公眾號(hào)文章)
    import pyquery
    import re
    
    
    def weixin_article_html_parser(html):
     """
     解析微信文章,返回包含文章主體的字典信息
     :param html: 文章HTML源代碼
     :return:
     """
    
     pq = pyquery.PyQuery(html)
    
     article = {
     "weixin_id": pq.find("#js_profile_qrcode "
     ".profile_inner .profile_meta").eq(0).find("span").text().strip(),
     "weixin_name": pq.find("#js_profile_qrcode .profile_inner strong").text().strip(),
     "account_desc": pq.find("#js_profile_qrcode .profile_inner "
     ".profile_meta").eq(1).find("span").text().strip(),
     "article_title": pq.find("title").text().strip(),
     "article_content": pq("#js_content").remove('script').text().replace(r"\r\n", ""),
     "is_orig": 1 if pq("#copyright_logo").length > 0 else 0,
     "article_source_url": pq("#js_sg_bar .meta_primary").attr('href') if pq(
     "#js_sg_bar .meta_primary").length > 0 else '',
    
     }
    
     # 使用正則表達(dá)式匹配頁(yè)面中js腳本中的內(nèi)容
     match = {
     "msg_cdn_url": {"regexp": "(?<=\").*(?=\")", "value": ""}, # 匹配文章封面圖
     "var ct": {"regexp": "(?<=\")\d{10}(?=\")", "value": ""}, # 匹配文章發(fā)布時(shí)間
     "publish_time": {"regexp": "(?<=\")\d{4}-\d{2}-\d{2}(?=\")", "value": ""}, # 匹配文章發(fā)布日期
     "msg_desc": {"regexp": "(?<=\").*(?=\")", "value": ""}, # 匹配文章簡(jiǎn)介
     "msg_link": {"regexp": "(?<=\").*(?=\")", "value": ""}, # 匹配文章鏈接
     "msg_source_url": {"regexp": "(?<=').*(?=')", "value": ""}, # 獲取原文鏈接
     "var biz": {"regexp": "(?<=\")\w{1}.+?(?=\")", "value": ""},
     "var idx": {"regexp": "(?<=\")\d{1}(?=\")", "value": ""},
     "var mid": {"regexp": "(?<=\")\d{10,}(?=\")", "value": ""},
     "var sn": {"regexp": "(?<=\")\w{1}.+?(?=\")", "value": ""},
     }
     count = 0
     for line in html.split("\n"):
     for item, value in match.items():
     if item in line:
     m = re.search(value["regexp"], line)
     if m is not None:
     count += 1
     match[item]["value"] = m.group(0)
     break
     if count >= len(match):
     break
    
     article["article_short_desc"] = match["msg_desc"]["value"]
     article["article_pos"] = int(match["var idx"]["value"])
     article["article_post_time"] = int(match["var ct"]["value"])
     article["article_post_date"] = match["publish_time"]["value"]
     article["article_cover_img"] = match["msg_cdn_url"]["value"]
     article["article_source_url"] = match["msg_source_url"]["value"]
     article["article_url"] = "https://mp.weixin.qq.com/s?__biz={biz}&mid={mid}&idx={idx}&sn={sn}".format(
     biz=match["var biz"]["value"],
     mid=match["var mid"]["value"],
     idx=match["var idx"]["value"],
     sn=match["var sn"]["value"],
     )
    
     return article
    
    
    if __name__ == '__main__':
    
     from pprint import pprint
     import requests
     url = ("https://mp.weixin.qq.com/s?__biz=MzI1NjA0MDg2Mw==&mid=2650682990&idx=1"
     "&sn=39419542de39a821bb5d1570ac50a313&scene=0#wechat_redirect")
     pprint(weixin_article_html_parser(requests.get(url).text))
    
    # {'account_desc': '夜聽(tīng),讓更多的家庭越來(lái)越幸福。',
    # 'article_content': '文字:安夢(mèng) \xa0 \xa0 聲音:劉筱 得到了什么?又失去了什么?',
    # 'article_cover_img': 'http://mmbiz.qpic.cn/mmbiz_jpg/4iaBNpgEXstYhQEnbiaD0AwbKhmCVWSeCPBQKgvnSSj9usO4q997wzoicNzl52K1sYSDHBicFGL7WdrmeS0K8niaiaaA/0?wx_fmt=jpeg',
    # 'article_pos': 1,
    # 'article_post_date': '2017-07-02',
    # 'article_post_time': 1499002202,
    # 'article_short_desc': '周日 來(lái)自劉筱的晚安問(wèn)候。',
    # 'article_source_url': '',
    # 'article_title': '【夜聽(tīng)】走到這里',
    # 'article_url': 'https://mp.weixin.qq.com/s?__biz=MzI1NjA0MDg2Mw==&mid=2650682990&idx=1&sn=39419542de39a821bb5d1570ac50a313',
    # 'is_orig': 0,
    # 'weixin_id': 'yetingfm',
    # 'weixin_name': '夜聽(tīng)'}

    使用phantomjs解析js渲染的頁(yè)面–微博搜索

    有些頁(yè)面采用復(fù)雜的js邏輯處理,包含各種Ajax請(qǐng)求,請(qǐng)求之間還包含一些加密操作,通過(guò)分析js邏輯重新渲染頁(yè)面拿到
    想要的數(shù)據(jù)可謂比登天還難,沒(méi)有堅(jiān)實(shí)的js基礎(chǔ),不熟悉各種js框架,搞明白這種頁(yè)面就別想了;
    采取類似瀏覽器的方式渲染頁(yè)面,直接獲取頁(yè)面HTML方便多了。

    例如:http://s.weibo.com/ 搜索出來(lái)的結(jié)果是使用js動(dòng)態(tài)渲染的,直接獲取HTML并不會(huì)得到搜索的結(jié)果,所以我們要運(yùn)行
    頁(yè)面中的js,將頁(yè)面渲染成功以后,再獲取它的HTML進(jìn)行解析;

    使用Python模擬登陸獲取cookie

    有些網(wǎng)站比較蛋疼,通常需要登錄之后才可以獲取數(shù)據(jù),下面展示一個(gè)簡(jiǎn)單的例子:用于登錄網(wǎng)站嗎,獲取cookie,然后可以用于其他請(qǐng)求

    但是,這里僅僅在沒(méi)有驗(yàn)證碼的情況下,如果要有短信驗(yàn)證,圖片驗(yàn)證,郵箱驗(yàn)證那就要另行設(shè)計(jì)了;

    目標(biāo)網(wǎng)站:http://www.newrank.cn,日期:2017-07-03,如果網(wǎng)站結(jié)構(gòu)更改,就需要修改代以下碼了;

    #!/usr/bin/env python3
    # encoding: utf-8
    import time
    from urllib import parse
    
    from selenium import webdriver
    from selenium.common.exceptions import TimeoutException, WebDriverException
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
    from pyquery import PyQuery
    
    
    def weibo_user_search(url: str):
     """通過(guò)phantomjs獲取搜索的頁(yè)面html"""
    
     desired_capabilities = DesiredCapabilities.CHROME.copy()
     desired_capabilities["phantomjs.page.settings.userAgent"] = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
     "AppleWebKit/537.36 (KHTML, like Gecko) "
     "Chrome/59.0.3071.104 Safari/537.36")
     desired_capabilities["phantomjs.page.settings.loadImages"] = True
     # 自定義頭部
     desired_capabilities["phantomjs.page.customHeaders.Upgrade-Insecure-Requests"] = 1
     desired_capabilities["phantomjs.page.customHeaders.Cache-Control"] = "max-age=0"
     desired_capabilities["phantomjs.page.customHeaders.Connection"] = "keep-alive"
    
     driver = webdriver.PhantomJS(executable_path="/usr/bin/phantomjs", # 設(shè)置phantomjs路徑
     desired_capabilities=desired_capabilities,
     service_log_path="ghostdriver.log",)
     # 設(shè)置對(duì)象的超時(shí)時(shí)間
     driver.implicitly_wait(1)
     # 設(shè)置頁(yè)面完全加載的超時(shí)時(shí)間,包括頁(yè)面全部渲染,異步同步腳本都執(zhí)行完成
     driver.set_page_load_timeout(60)
     # 設(shè)置異步腳本的超時(shí)時(shí)間
     driver.set_script_timeout(60)
    
     driver.maximize_window()
     try:
     driver.get(url=url)
     time.sleep(1)
     try:
     # 打開(kāi)頁(yè)面之后做一些操作
     company = driver.find_element_by_css_selector("p.company")
     ActionChains(driver).move_to_element(company)
     except WebDriverException:
     pass
     html = driver.page_source
     pq = PyQuery(html)
     person_lists = pq.find("div.list_person")
     if person_lists.length > 0:
     for index in range(person_lists.length):
     person_ele = person_lists.eq(index)
     print(person_ele.find(".person_name > a.W_texta").attr("title"))
     return html
     except (TimeoutException, Exception) as e:
     print(e)
     finally:
     driver.quit()
    
    if __name__ == '__main__':
     weibo_user_search(url="http://s.weibo.com/user/%s" % parse.quote("新聞"))
    # 央視新聞
    # 新浪新聞
    # 新聞
    # 新浪新聞客戶端
    # 中國(guó)新聞周刊
    # 中國(guó)新聞網(wǎng)
    # 每日經(jīng)濟(jì)新聞
    # 澎湃新聞
    # 網(wǎng)易新聞客戶端
    # 鳳凰新聞客戶端
    # 皇馬新聞
    # 網(wǎng)絡(luò)新聞聯(lián)播
    # CCTV5體育新聞
    # 曼聯(lián)新聞
    # 搜狐新聞客戶端
    # 巴薩新聞
    # 新聞日日睇
    # 新垣結(jié)衣新聞社
    # 看看新聞KNEWS
    # 央視新聞評(píng)論

    使用Python模擬登陸獲取cookie

    有些網(wǎng)站比較蛋疼,通常需要登錄之后才可以獲取數(shù)據(jù),下面展示一個(gè)簡(jiǎn)單的例子:用于登錄網(wǎng)站嗎,獲取cookie,然后可以用于其他請(qǐng)求

    但是,這里僅僅在沒(méi)有驗(yàn)證碼的情況下,如果要有短信驗(yàn)證,圖片驗(yàn)證,郵箱驗(yàn)證那就要另行設(shè)計(jì)了;

    目標(biāo)網(wǎng)站:http://www.newrank.cn,日期:2017-07-03,如果網(wǎng)站結(jié)構(gòu)更改,就需要修改代以下碼了;

    #!/usr/bin/env python3
    # encoding: utf-8
    
    from time import sleep
    from pprint import pprint
    
    from selenium.common.exceptions import TimeoutException, WebDriverException
    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
    from selenium import webdriver
    
    
    def login_newrank():
     """登錄新榜,獲取他的cookie信息"""
    
     desired_capabilities = DesiredCapabilities.CHROME.copy()
     desired_capabilities["phantomjs.page.settings.userAgent"] = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
     "AppleWebKit/537.36 (KHTML, like Gecko) "
     "Chrome/59.0.3071.104 Safari/537.36")
     desired_capabilities["phantomjs.page.settings.loadImages"] = True
    
     # 自定義頭部
     desired_capabilities["phantomjs.page.customHeaders.Upgrade-Insecure-Requests"] = 1
     desired_capabilities["phantomjs.page.customHeaders.Cache-Control"] = "max-age=0"
     desired_capabilities["phantomjs.page.customHeaders.Connection"] = "keep-alive"
    
     # 填寫(xiě)自己的賬戶進(jìn)行測(cè)試
     user = {
     "mobile": "user",
     "password": "password"
     }
    
     print("login account: %s" % user["mobile"])
    
     driver = webdriver.PhantomJS(executable_path="/usr/bin/phantomjs",
     desired_capabilities=desired_capabilities,
     service_log_path="ghostdriver.log", )
    
     # 設(shè)置對(duì)象的超時(shí)時(shí)間
     driver.implicitly_wait(1)
     # 設(shè)置頁(yè)面完全加載的超時(shí)時(shí)間,包括頁(yè)面全部渲染,異步同步腳本都執(zhí)行完成
     driver.set_page_load_timeout(60)
     # 設(shè)置異步腳本的超時(shí)時(shí)間
     driver.set_script_timeout(60)
    
     driver.maximize_window()
    
     try:
     driver.get(url="http://www.newrank.cn/public/login/login.html?back=http%3A//www.newrank.cn/")
     driver.find_element_by_css_selector(".login-normal-tap:nth-of-type(2)").click()
     sleep(0.2)
     driver.find_element_by_id("account_input").send_keys(user["mobile"])
     sleep(0.5)
     driver.find_element_by_id("password_input").send_keys(user["password"])
     sleep(0.5)
     driver.find_element_by_id("pwd_confirm").click()
     sleep(3)
     cookies = {user["name"]: user["value"] for user in driver.get_cookies()}
     pprint(cookies)
    
     except TimeoutException as exc:
     print(exc)
     except WebDriverException as exc:
     print(exc)
     finally:
     driver.quit()
    
    if __name__ == '__main__':
     login_newrank()
    # login account: 15395100590
    # {'CNZZDATA1253878005': '1487200824-1499071649-%7C1499071649',
    # 'Hm_lpvt_a19fd7224d30e3c8a6558dcb38c4beed': '1499074715',
    # 'Hm_lvt_a19fd7224d30e3c8a6558dcb38c4beed': '1499074685,1499074713',
    # 'UM_distinctid': '15d07d0d4dd82b-054b56417-9383666-c0000-15d07d0d4deace',
    # 'name': '15395100590',
    # 'rmbuser': 'true',
    # 'token': 'A7437A03346B47A9F768730BAC81C514',
    # 'useLoginAccount': 'true'}

    在獲取cookie之后就可以將獲得的cookie添加到后續(xù)的請(qǐng)求中了,但是因?yàn)閏ookie是具有有效期的,因此需要定時(shí)更新;
    可以通過(guò)設(shè)計(jì)一個(gè)cookie池來(lái)實(shí)現(xiàn),動(dòng)態(tài)定時(shí)登錄一批賬號(hào),獲取cookie之后存放在數(shù)據(jù)庫(kù)中(redis,MySQL等等),
    請(qǐng)求的時(shí)候從數(shù)據(jù)庫(kù)中獲取一條可用cookie,并且添加在請(qǐng)求中訪問(wèn);

    使用pyqt5爬個(gè)數(shù)據(jù)試試(PyQt 5.9.2)
    import sys
    import csv
    
    import pyquery
    
    from PyQt5.QtCore import QUrl
    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtWebEngineWidgets import QWebEngineView
    
    
    class Browser(QWebEngineView):
    
     def __init__(self):
     super(Browser, self).__init__()
     self.__results = []
     self.loadFinished.connect(self.__result_available)
    
     @property
     def results(self):
     return self.__results
    
     def __result_available(self):
     self.page().toHtml(self.__parse_html)
    
     def __parse_html(self, html):
     pq = pyquery.PyQuery(html)
     for rows in [pq.find("#table_list tr"), pq.find("#more_list tr")]:
     for row in rows.items():
     columns = row.find("td")
     d = {
     "avatar": columns.eq(1).find("img").attr("src"),
     "url": columns.eq(1).find("a").attr("href"),
     "name": columns.eq(1).find("a").attr("title"),
     "fans_number": columns.eq(2).text(),
     "view_num": columns.eq(3).text(),
     "comment_num": columns.eq(4).text(),
     "post_count": columns.eq(5).text(),
     "newrank_index": columns.eq(6).text(),
     }
     self.__results.append(d)
    
     with open("results.csv", "a+", encoding="utf-8") as f:
     writer = csv.DictWriter(f, fieldnames=["name", "fans_number", "view_num", "comment_num", "post_count",
     "newrank_index", "url", "avatar"])
     writer.writerows(self.results)
    
     def open(self, url: str):
     self.load(QUrl(url))
    
    
    if __name__ == '__main__':
     app = QApplication(sys.argv)
     browser = Browser()
     browser.open("https://www.newrank.cn/public/info/list.html?period=toutiao_day&type=data")
     browser.show()
     app.exec_()

    持續(xù)更新中:

    5. 使用Fiddler抓包分析

    1. 瀏覽器抓包
    2. fiddler手機(jī)抓包

    6. 使用anyproxy抓取客戶端數(shù)據(jù)–客戶端數(shù)據(jù)采集

    7. 關(guān)于開(kāi)發(fā)高性能爬蟲(chóng)的總結(jié)

    關(guān)注微信公眾號(hào)“python社區(qū)營(yíng)”了解更多技術(shù)

    原文鏈接:https://www.cnblogs.com/pypypy/p/12019283.html

    用Python開(kāi)發(fā)爬蟲(chóng)是一件很輕松愉悅的事情,因?yàn)槠湎嚓P(guān)庫(kù)較多,而且使用方便,短短十幾行代碼就可以完成一個(gè)爬蟲(chóng)的開(kāi)發(fā);
    但是,在應(yīng)對(duì)具有反爬措施的網(wǎng)站,使用js動(dòng)態(tài)加載的網(wǎng)站,App采集的時(shí)候就得動(dòng)動(dòng)腦子了;并且在開(kāi)發(fā)分布式爬蟲(chóng),高性能爬蟲(chóng)的時(shí)候更得用心設(shè)計(jì)。

    Python開(kāi)發(fā)爬蟲(chóng)常用的工具總結(jié)

    1. reqeusts:Python HTTP網(wǎng)絡(luò)請(qǐng)求庫(kù);
    2. pyquery: Python HTML DOM結(jié)構(gòu)解析庫(kù),采用類似JQuery的語(yǔ)法;
    3. BeautifulSoup:python HTML以及XML結(jié)構(gòu)解析;
    4. selenium:Python自動(dòng)化測(cè)試框架,可以用于爬蟲(chóng);
    5. phantomjs:無(wú)頭瀏覽器,可以配合selenium獲取js動(dòng)態(tài)加載的內(nèi)容;
    6. re:python內(nèi)建正則表達(dá)式模塊;
    7. fiddler:抓包工具,原理就是是一個(gè)代理服務(wù)器,可以抓取手機(jī)包;
    8. anyproxy:代理服務(wù)器,可以自己撰寫(xiě)rule截取request或者response,通常用于客戶端采集;
    9. celery:Python分布式計(jì)算框架,可用于開(kāi)發(fā)分布式爬蟲(chóng);
    10. gevent:Python基于協(xié)程的網(wǎng)絡(luò)庫(kù),可用于開(kāi)發(fā)高性能爬蟲(chóng)
    11. grequests:異步requests
    12. aiohttp:異步http client/server框架
    13. asyncio:python內(nèi)建異步io,事件循環(huán)庫(kù)
    14. uvloop:一個(gè)非??焖俚氖录h(huán)庫(kù),配合asyncio效率極高
    15. concurrent:Python內(nèi)建用于并發(fā)任務(wù)執(zhí)行的擴(kuò)展
    16. scrapy:python 爬蟲(chóng)框架;
    17. Splash:一個(gè)JavaScript渲染服務(wù),相當(dāng)于一個(gè)輕量級(jí)的瀏覽器,配合lua腳本通過(guò)他的http API 解析頁(yè)面;
    18. Splinter:開(kāi)源自動(dòng)化Python web測(cè)試工具
    19. pyspider:Python爬蟲(chóng)系統(tǒng)

    網(wǎng)頁(yè)抓取思路

      1. 數(shù)據(jù)是否可以直接從HTML中獲?。繑?shù)據(jù)直接嵌套在頁(yè)面的HTML結(jié)構(gòu)中;
      2. 數(shù)據(jù)是否使用JS動(dòng)態(tài)渲染到頁(yè)面中的?數(shù)據(jù)嵌套在js代碼中,然后采用js加載到頁(yè)面或者采用ajax渲染;
      3. 獲取的頁(yè)面使用是否需要認(rèn)證?需要登錄后頁(yè)面才可以訪問(wèn);
      4. 數(shù)據(jù)是否直接可以通過(guò)API得到?有些數(shù)據(jù)是可以直接通過(guò)api獲取到,省去解析HTML的麻煩,大多數(shù)API都是以JSON格式返回?cái)?shù)據(jù);
      5. 來(lái)自客戶端的數(shù)據(jù)如何采集?例如:微信APP和微信客戶端

    如何應(yīng)對(duì)反爬

    1. 不要太過(guò)分,控制爬蟲(chóng)的速率,別把人家整垮了,那就兩敗俱傷了;
    2. 使用代理隱藏真實(shí)IP,并且實(shí)現(xiàn)反爬;
    3. 讓爬蟲(chóng)看起來(lái)像人類用戶,選擇性滴設(shè)置以下HTTP頭部:Host:https://www.baidu.comConnection:keep-aliveAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36Referer: http://s.weibo.com/user/gamelife1314&Refer=indexAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.8
    4. 查看網(wǎng)站的cookie,在某些情況下,請(qǐng)求需要添加cookie用于通過(guò)服務(wù)端的一些校驗(yàn);

    案例說(shuō)明

    靜態(tài)頁(yè)面解析(獲取微信公眾號(hào)文章)
    import pyquery
    import re
    
    
    def weixin_article_html_parser(html):
     """
     解析微信文章,返回包含文章主體的字典信息
     :param html: 文章HTML源代碼
     :return:
     """
    
     pq = pyquery.PyQuery(html)
    
     article = {
     "weixin_id": pq.find("#js_profile_qrcode "
     ".profile_inner .profile_meta").eq(0).find("span").text().strip(),
     "weixin_name": pq.find("#js_profile_qrcode .profile_inner strong").text().strip(),
     "account_desc": pq.find("#js_profile_qrcode .profile_inner "
     ".profile_meta").eq(1).find("span").text().strip(),
     "article_title": pq.find("title").text().strip(),
     "article_content": pq("#js_content").remove('script').text().replace(r"\r\n", ""),
     "is_orig": 1 if pq("#copyright_logo").length > 0 else 0,
     "article_source_url": pq("#js_sg_bar .meta_primary").attr('href') if pq(
     "#js_sg_bar .meta_primary").length > 0 else '',
    
     }
    
     # 使用正則表達(dá)式匹配頁(yè)面中js腳本中的內(nèi)容
     match = {
     "msg_cdn_url": {"regexp": "(?<=\").*(?=\")", "value": ""}, # 匹配文章封面圖
     "var ct": {"regexp": "(?<=\")\d{10}(?=\")", "value": ""}, # 匹配文章發(fā)布時(shí)間
     "publish_time": {"regexp": "(?<=\")\d{4}-\d{2}-\d{2}(?=\")", "value": ""}, # 匹配文章發(fā)布日期
     "msg_desc": {"regexp": "(?<=\").*(?=\")", "value": ""}, # 匹配文章簡(jiǎn)介
     "msg_link": {"regexp": "(?<=\").*(?=\")", "value": ""}, # 匹配文章鏈接
     "msg_source_url": {"regexp": "(?<=').*(?=')", "value": ""}, # 獲取原文鏈接
     "var biz": {"regexp": "(?<=\")\w{1}.+?(?=\")", "value": ""},
     "var idx": {"regexp": "(?<=\")\d{1}(?=\")", "value": ""},
     "var mid": {"regexp": "(?<=\")\d{10,}(?=\")", "value": ""},
     "var sn": {"regexp": "(?<=\")\w{1}.+?(?=\")", "value": ""},
     }
     count = 0
     for line in html.split("\n"):
     for item, value in match.items():
     if item in line:
     m = re.search(value["regexp"], line)
     if m is not None:
     count += 1
     match[item]["value"] = m.group(0)
     break
     if count >= len(match):
     break
    
     article["article_short_desc"] = match["msg_desc"]["value"]
     article["article_pos"] = int(match["var idx"]["value"])
     article["article_post_time"] = int(match["var ct"]["value"])
     article["article_post_date"] = match["publish_time"]["value"]
     article["article_cover_img"] = match["msg_cdn_url"]["value"]
     article["article_source_url"] = match["msg_source_url"]["value"]
     article["article_url"] = "https://mp.weixin.qq.com/s?__biz={biz}&mid={mid}&idx={idx}&sn={sn}".format(
     biz=match["var biz"]["value"],
     mid=match["var mid"]["value"],
     idx=match["var idx"]["value"],
     sn=match["var sn"]["value"],
     )
    
     return article
    
    
    if __name__ == '__main__':
    
     from pprint import pprint
     import requests
     url = ("https://mp.weixin.qq.com/s?__biz=MzI1NjA0MDg2Mw==&mid=2650682990&idx=1"
     "&sn=39419542de39a821bb5d1570ac50a313&scene=0#wechat_redirect")
     pprint(weixin_article_html_parser(requests.get(url).text))
    
    # {'account_desc': '夜聽(tīng),讓更多的家庭越來(lái)越幸福。',
    # 'article_content': '文字:安夢(mèng) \xa0 \xa0 聲音:劉筱 得到了什么?又失去了什么?',
    # 'article_cover_img': 'http://mmbiz.qpic.cn/mmbiz_jpg/4iaBNpgEXstYhQEnbiaD0AwbKhmCVWSeCPBQKgvnSSj9usO4q997wzoicNzl52K1sYSDHBicFGL7WdrmeS0K8niaiaaA/0?wx_fmt=jpeg',
    # 'article_pos': 1,
    # 'article_post_date': '2017-07-02',
    # 'article_post_time': 1499002202,
    # 'article_short_desc': '周日 來(lái)自劉筱的晚安問(wèn)候。',
    # 'article_source_url': '',
    # 'article_title': '【夜聽(tīng)】走到這里',
    # 'article_url': 'https://mp.weixin.qq.com/s?__biz=MzI1NjA0MDg2Mw==&mid=2650682990&idx=1&sn=39419542de39a821bb5d1570ac50a313',
    # 'is_orig': 0,
    # 'weixin_id': 'yetingfm',
    # 'weixin_name': '夜聽(tīng)'}

    使用phantomjs解析js渲染的頁(yè)面–微博搜索

    有些頁(yè)面采用復(fù)雜的js邏輯處理,包含各種Ajax請(qǐng)求,請(qǐng)求之間還包含一些加密操作,通過(guò)分析js邏輯重新渲染頁(yè)面拿到
    想要的數(shù)據(jù)可謂比登天還難,沒(méi)有堅(jiān)實(shí)的js基礎(chǔ),不熟悉各種js框架,搞明白這種頁(yè)面就別想了;
    采取類似瀏覽器的方式渲染頁(yè)面,直接獲取頁(yè)面HTML方便多了。

    例如:http://s.weibo.com/ 搜索出來(lái)的結(jié)果是使用js動(dòng)態(tài)渲染的,直接獲取HTML并不會(huì)得到搜索的結(jié)果,所以我們要運(yùn)行
    頁(yè)面中的js,將頁(yè)面渲染成功以后,再獲取它的HTML進(jìn)行解析;

    使用Python模擬登陸獲取cookie

    有些網(wǎng)站比較蛋疼,通常需要登錄之后才可以獲取數(shù)據(jù),下面展示一個(gè)簡(jiǎn)單的例子:用于登錄網(wǎng)站嗎,獲取cookie,然后可以用于其他請(qǐng)求

    但是,這里僅僅在沒(méi)有驗(yàn)證碼的情況下,如果要有短信驗(yàn)證,圖片驗(yàn)證,郵箱驗(yàn)證那就要另行設(shè)計(jì)了;

    目標(biāo)網(wǎng)站:http://www.newrank.cn,日期:2017-07-03,如果網(wǎng)站結(jié)構(gòu)更改,就需要修改代以下碼了;

    #!/usr/bin/env python3
    # encoding: utf-8
    import time
    from urllib import parse
    
    from selenium import webdriver
    from selenium.common.exceptions import TimeoutException, WebDriverException
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
    from pyquery import PyQuery
    
    
    def weibo_user_search(url: str):
     """通過(guò)phantomjs獲取搜索的頁(yè)面html"""
    
     desired_capabilities = DesiredCapabilities.CHROME.copy()
     desired_capabilities["phantomjs.page.settings.userAgent"] = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
     "AppleWebKit/537.36 (KHTML, like Gecko) "
     "Chrome/59.0.3071.104 Safari/537.36")
     desired_capabilities["phantomjs.page.settings.loadImages"] = True
     # 自定義頭部
     desired_capabilities["phantomjs.page.customHeaders.Upgrade-Insecure-Requests"] = 1
     desired_capabilities["phantomjs.page.customHeaders.Cache-Control"] = "max-age=0"
     desired_capabilities["phantomjs.page.customHeaders.Connection"] = "keep-alive"
    
     driver = webdriver.PhantomJS(executable_path="/usr/bin/phantomjs", # 設(shè)置phantomjs路徑
     desired_capabilities=desired_capabilities,
     service_log_path="ghostdriver.log",)
     # 設(shè)置對(duì)象的超時(shí)時(shí)間
     driver.implicitly_wait(1)
     # 設(shè)置頁(yè)面完全加載的超時(shí)時(shí)間,包括頁(yè)面全部渲染,異步同步腳本都執(zhí)行完成
     driver.set_page_load_timeout(60)
     # 設(shè)置異步腳本的超時(shí)時(shí)間
     driver.set_script_timeout(60)
    
     driver.maximize_window()
     try:
     driver.get(url=url)
     time.sleep(1)
     try:
     # 打開(kāi)頁(yè)面之后做一些操作
     company = driver.find_element_by_css_selector("p.company")
     ActionChains(driver).move_to_element(company)
     except WebDriverException:
     pass
     html = driver.page_source
     pq = PyQuery(html)
     person_lists = pq.find("div.list_person")
     if person_lists.length > 0:
     for index in range(person_lists.length):
     person_ele = person_lists.eq(index)
     print(person_ele.find(".person_name > a.W_texta").attr("title"))
     return html
     except (TimeoutException, Exception) as e:
     print(e)
     finally:
     driver.quit()
    
    if __name__ == '__main__':
     weibo_user_search(url="http://s.weibo.com/user/%s" % parse.quote("新聞"))
    # 央視新聞
    # 新浪新聞
    # 新聞
    # 新浪新聞客戶端
    # 中國(guó)新聞周刊
    # 中國(guó)新聞網(wǎng)
    # 每日經(jīng)濟(jì)新聞
    # 澎湃新聞
    # 網(wǎng)易新聞客戶端
    # 鳳凰新聞客戶端
    # 皇馬新聞
    # 網(wǎng)絡(luò)新聞聯(lián)播
    # CCTV5體育新聞
    # 曼聯(lián)新聞
    # 搜狐新聞客戶端
    # 巴薩新聞
    # 新聞日日睇
    # 新垣結(jié)衣新聞社
    # 看看新聞KNEWS
    # 央視新聞評(píng)論

    使用Python模擬登陸獲取cookie

    有些網(wǎng)站比較蛋疼,通常需要登錄之后才可以獲取數(shù)據(jù),下面展示一個(gè)簡(jiǎn)單的例子:用于登錄網(wǎng)站嗎,獲取cookie,然后可以用于其他請(qǐng)求

    但是,這里僅僅在沒(méi)有驗(yàn)證碼的情況下,如果要有短信驗(yàn)證,圖片驗(yàn)證,郵箱驗(yàn)證那就要另行設(shè)計(jì)了;

    目標(biāo)網(wǎng)站:http://www.newrank.cn,日期:2017-07-03,如果網(wǎng)站結(jié)構(gòu)更改,就需要修改代以下碼了;

    #!/usr/bin/env python3
    # encoding: utf-8
    
    from time import sleep
    from pprint import pprint
    
    from selenium.common.exceptions import TimeoutException, WebDriverException
    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
    from selenium import webdriver
    
    
    def login_newrank():
     """登錄新榜,獲取他的cookie信息"""
    
     desired_capabilities = DesiredCapabilities.CHROME.copy()
     desired_capabilities["phantomjs.page.settings.userAgent"] = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
     "AppleWebKit/537.36 (KHTML, like Gecko) "
     "Chrome/59.0.3071.104 Safari/537.36")
     desired_capabilities["phantomjs.page.settings.loadImages"] = True
    
     # 自定義頭部
     desired_capabilities["phantomjs.page.customHeaders.Upgrade-Insecure-Requests"] = 1
     desired_capabilities["phantomjs.page.customHeaders.Cache-Control"] = "max-age=0"
     desired_capabilities["phantomjs.page.customHeaders.Connection"] = "keep-alive"
    
     # 填寫(xiě)自己的賬戶進(jìn)行測(cè)試
     user = {
     "mobile": "user",
     "password": "password"
     }
    
     print("login account: %s" % user["mobile"])
    
     driver = webdriver.PhantomJS(executable_path="/usr/bin/phantomjs",
     desired_capabilities=desired_capabilities,
     service_log_path="ghostdriver.log", )
    
     # 設(shè)置對(duì)象的超時(shí)時(shí)間
     driver.implicitly_wait(1)
     # 設(shè)置頁(yè)面完全加載的超時(shí)時(shí)間,包括頁(yè)面全部渲染,異步同步腳本都執(zhí)行完成
     driver.set_page_load_timeout(60)
     # 設(shè)置異步腳本的超時(shí)時(shí)間
     driver.set_script_timeout(60)
    
     driver.maximize_window()
    
     try:
     driver.get(url="http://www.newrank.cn/public/login/login.html?back=http%3A//www.newrank.cn/")
     driver.find_element_by_css_selector(".login-normal-tap:nth-of-type(2)").click()
     sleep(0.2)
     driver.find_element_by_id("account_input").send_keys(user["mobile"])
     sleep(0.5)
     driver.find_element_by_id("password_input").send_keys(user["password"])
     sleep(0.5)
     driver.find_element_by_id("pwd_confirm").click()
     sleep(3)
     cookies = {user["name"]: user["value"] for user in driver.get_cookies()}
     pprint(cookies)
    
     except TimeoutException as exc:
     print(exc)
     except WebDriverException as exc:
     print(exc)
     finally:
     driver.quit()
    
    if __name__ == '__main__':
     login_newrank()
    # login account: 15395100590
    # {'CNZZDATA1253878005': '1487200824-1499071649-%7C1499071649',
    # 'Hm_lpvt_a19fd7224d30e3c8a6558dcb38c4beed': '1499074715',
    # 'Hm_lvt_a19fd7224d30e3c8a6558dcb38c4beed': '1499074685,1499074713',
    # 'UM_distinctid': '15d07d0d4dd82b-054b56417-9383666-c0000-15d07d0d4deace',
    # 'name': '15395100590',
    # 'rmbuser': 'true',
    # 'token': 'A7437A03346B47A9F768730BAC81C514',
    # 'useLoginAccount': 'true'}

    在獲取cookie之后就可以將獲得的cookie添加到后續(xù)的請(qǐng)求中了,但是因?yàn)閏ookie是具有有效期的,因此需要定時(shí)更新;
    可以通過(guò)設(shè)計(jì)一個(gè)cookie池來(lái)實(shí)現(xiàn),動(dòng)態(tài)定時(shí)登錄一批賬號(hào),獲取cookie之后存放在數(shù)據(jù)庫(kù)中(redis,MySQL等等),
    請(qǐng)求的時(shí)候從數(shù)據(jù)庫(kù)中獲取一條可用cookie,并且添加在請(qǐng)求中訪問(wèn);

    使用pyqt5爬個(gè)數(shù)據(jù)試試(PyQt 5.9.2)
    import sys
    import csv
    
    import pyquery
    
    from PyQt5.QtCore import QUrl
    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtWebEngineWidgets import QWebEngineView
    
    
    class Browser(QWebEngineView):
    
     def __init__(self):
     super(Browser, self).__init__()
     self.__results = []
     self.loadFinished.connect(self.__result_available)
    
     @property
     def results(self):
     return self.__results
    
     def __result_available(self):
     self.page().toHtml(self.__parse_html)
    
     def __parse_html(self, html):
     pq = pyquery.PyQuery(html)
     for rows in [pq.find("#table_list tr"), pq.find("#more_list tr")]:
     for row in rows.items():
     columns = row.find("td")
     d = {
     "avatar": columns.eq(1).find("img").attr("src"),
     "url": columns.eq(1).find("a").attr("href"),
     "name": columns.eq(1).find("a").attr("title"),
     "fans_number": columns.eq(2).text(),
     "view_num": columns.eq(3).text(),
     "comment_num": columns.eq(4).text(),
     "post_count": columns.eq(5).text(),
     "newrank_index": columns.eq(6).text(),
     }
     self.__results.append(d)
    
     with open("results.csv", "a+", encoding="utf-8") as f:
     writer = csv.DictWriter(f, fieldnames=["name", "fans_number", "view_num", "comment_num", "post_count",
     "newrank_index", "url", "avatar"])
     writer.writerows(self.results)
    
     def open(self, url: str):
     self.load(QUrl(url))
    
    
    if __name__ == '__main__':
     app = QApplication(sys.argv)
     browser = Browser()
     browser.open("https://www.newrank.cn/public/info/list.html?period=toutiao_day&type=data")
     browser.show()
     app.exec_()

    持續(xù)更新中:

    5. 使用Fiddler抓包分析

    1. 瀏覽器抓包
    2. fiddler手機(jī)抓包

    6. 使用anyproxy抓取客戶端數(shù)據(jù)–客戶端數(shù)據(jù)采集

    7. 關(guān)于開(kāi)發(fā)高性能爬蟲(chóng)的總結(jié)

    關(guān)注微信公眾號(hào)“python社區(qū)營(yíng)”了解更多技術(shù)

    原文鏈接:https://www.cnblogs.com/pypypy/p/12019283.html

網(wǎng)站首頁(yè)   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有