如何在Pycharm中制作自己的爬蟲代碼模板
寫作背景
最近本菜雞有幾個(gè)網(wǎng)站想要爬,每個(gè)爬蟲的代碼不一樣,但 有某種聯(lián)系,可以抽出一部分通用的代碼制成模板,減少代碼工作量,于是就有了這篇文章。
如果覺得我這篇文章寫的好的話,能不能給我 點(diǎn)個(gè)贊 ,評論 、收藏 一條龍(☆▽☆)。如果要點(diǎn)個(gè) 關(guān)注 的話也不是不可以。
如果 有什么問題,還 請各位大佬提出,不勝感激。
爬蟲代碼
我的爬蟲代碼都是使用的 自己 寫的 多線程。
因?yàn)槲业拇a能力很差,所以如果代碼有哪里讓各位大佬倍感不適,請及時(shí)在評論區(qū) 指出,謝謝各位大佬。
我的代碼如下:
#!/usr/bin/python3 # -*- coding=utf-8 -*- # @Author : lhys # @FileName: proxy_tool.py import requests import threading timeout = 300 lock = threading.Lock() # 請求頭用自己的 headers = { '': '' } class MyProxy: def __init__(self, proxy_api='', proxy_server='', max_use=5000, try_count=5): if not (proxy_api or proxy_server): raise TypeError('Proxy_api and proxy_server cannot be empty at the same time.') self.proxies = None if not proxy_server else { 'http': proxy_server, 'https': proxy_server } # 代理API self.proxy_api = proxy_api # 代理 IP 最大使用次數(shù) self.max_use = max_use # 測試代理 IP 次數(shù),超過次數(shù)即認(rèn)為代理 IP 不可用 self.try_count = try_count # 是否爬蟲請求出錯(cuò),如果出錯(cuò),直接更換 IP self.flag = 0 # 代理 IP 剩余生存時(shí)間 self.proxy_ttl = 0 # 各種鎖 self.lock = threading.Lock() self.ttl_lock = threading.Lock() self.flag_lock = threading.Lock() def set_flag(self): self.flag_lock.acquire() self.flag = 1 self.flag_lock.release() def get_flag(self): self.flag_lock.acquire() flag = self.flag self.flag_lock.release() return flag def decrease_ttl(self): self.ttl_lock.acquire() self.proxy_ttl -= 1 self.ttl_lock.release() def get_ttl(self): self.ttl_lock.acquire() ttl = self.proxy_ttl self.ttl_lock.release() return ttl def set_ttl(self): self.ttl_lock.acquire() self.proxy_ttl = self.max_use self.ttl_lock.release() def get_proxy(self): self.lock.acquire() proxy = self.proxies self.lock.release() return proxy def set_proxy(self): if self.proxy_ttl > 0 and self.flag == 0: return old = self.proxies if self.flag == 1: for try_count in range(self.try_count): try: requests.get('https://www.baidu.com', headers=headers, proxies=old, timeout=timeout) print(f'Test proxy {old} successfully.') return except requests.exceptions.ProxyError or requests.exceptions.ConnectionError or requests.exceptions.ConnectTimeout: print(f'Test proxy {old} failed.') break except Exception as e: print(e) if not self.proxy_api: raise ValueError('代理 IP 不可用,且代理 IP API未設(shè)置。') while True: res = requests.get(self.proxy_api) # 這一部分按照自己的代理 IP 文檔來,僅供參考 try: if res.json()["ERRORCODE"] == "0": ip, port = res.json()["RESULT"][0]['ip'], res.json()["RESULT"][0]['port'] self.lock.acquire() self.proxies = { 'http': 'http://%s:%s' % (ip, port), 'https': 'http://%s:%s' % (ip, port) } print(f'Set proxy: {ip}:{port}.') self.flag = 0 self.lock.release() self.set_ttl() return else: print(f'Set proxy failed.') except Exception as e: print(e) Proxy = MyProxy() def request_by_proxy(url, use_proxy=True): while True: try: # 使用代理 if use_proxy: proxy_ttl = Proxy.get_ttl() print(proxy_ttl) # 如果 超過最大使用次數(shù) 或者 請求出現(xiàn)錯(cuò)誤,重新設(shè)置 IP if proxy_ttl <= 0 or Proxy.get_flag(): Proxy.set_proxy() print(Proxy.get_ttl()) proxy = Proxy.get_proxy() lock.acquire() res = requests.get(url, headers=headers, proxies=proxy, timeout=timeout) lock.release() Proxy.decrease_ttl() return res else: res = requests.get(url, headers=headers, timeout=timeout) return res except requests.exceptions.ProxyError as pe: if use_proxy: lock.release() print(f'Proxy {Proxy.proxies} is not available, reason: {pe}.') Proxy.set_flag() except requests.exceptions.Timeout as t: if use_proxy: lock.release() print(f'Time out, reason: {t}.') Proxy.set_flag() except Exception as e: if use_proxy: lock.release() print(e)
#!/usr/bin/python3 # -*- coding=utf-8 -*- # @Author : lhys # @FileName: spider.py import time import threading from multiprocessing import Queue from proxy_tool import request_by_proxy threshold = 30 queue = Queue() class Spider(threading.Thread): def __init__(self, use_proxy=True): super(Spider, self).__init__() self.use_proxy = use_proxy def get_data(self, url): try: res = request_by_proxy(url, self.use_proxy) # 響應(yīng)處理 pass except Exception as e: print(e) return def run(self): while True: # 如果隊(duì)列空了,等待一會兒。 # 過了指定的時(shí)間后,如果隊(duì)列出現(xiàn)數(shù)據(jù),就繼續(xù)爬 # 如果隊(duì)列還是空的,停止線程 if queue.empty(): time.sleep(threshold) if not queue.empty(): url = queue.get() self.get_data(url) time.sleep(threshold) else: print('Queue is empty.') return
在 Pycharm 中設(shè)置代碼模板
打開 File -> settings -> Editor -> Live Templates,點(diǎn)擊 Python,如下圖所示:
可以看到,已經(jīng)有一些自動補(bǔ)全的模板了,以 TCP_Client 為例,如下圖所示:
可以看到 Pycharm 有提示。
使用 TCP_Client。
如果我們要制作自己的代碼模板,就點(diǎn)擊 + ,如下圖所示:
點(diǎn)擊 Live Template 。(第二個(gè)是 創(chuàng)建模板組,目前我們不需要,直接在 Python 模板組下創(chuàng)建就好了)。
其中:
- Abbreviation 譯為 縮寫,就是 自動補(bǔ)全框中出現(xiàn)的名字 。
- Description 譯為 描述,就是 對這個(gè)代碼模板進(jìn)行描述,可空。
- Template text 譯為 模板文本,就是 要設(shè)置的模板代碼。
然后在下方 define 處選擇在哪個(gè)模板組中定義,可 根據(jù)自己需求或喜好選擇模板組 ,我這里選擇 Python ,點(diǎn)擊 ok 。
測試一下:
成功完成任務(wù)?。?!?
到此這篇關(guān)于如何在Pycharm中制作自己的爬蟲代碼模板的文章就介紹到這了,更多相關(guān)Pycharm制作爬蟲代碼模板內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python圖像濾波處理操作示例【基于ImageFilter類】
這篇文章主要介紹了Python圖像濾波處理操作,結(jié)合實(shí)例形式分析了Python基于ImageFilter類實(shí)現(xiàn)的濾波處理相關(guān)操作技巧,需要的朋友可以參考下2019-01-01將 Ubuntu 16 和 18 上的 python 升級到最新 python3.8 的方法教程
這篇文章主要介紹了如何將 Ubuntu 16 和 18 上的 python 升級到最新 3.8 版,本文通過實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03對python中數(shù)據(jù)集劃分函數(shù)StratifiedShuffleSplit的使用詳解
今天小編就為大家分享一篇對python中數(shù)據(jù)集劃分函數(shù)StratifiedShuffleSplit的使用詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12對Python定時(shí)任務(wù)的啟動和停止方法詳解
今天小編就為大家分享一篇對Python定時(shí)任務(wù)的啟動和停止方法詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-02-02如何利用Python隨機(jī)從list中挑選一個(gè)元素
這篇文章主要介紹了如何利用Python隨機(jī)從list中挑選一個(gè)元素,文章通過研究從列表中選擇隨機(jī)元素的不同實(shí)現(xiàn)方法展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-05-05Python交互環(huán)境下實(shí)現(xiàn)輸入代碼
今天小編就為大家分享一篇Python交互環(huán)境下實(shí)現(xiàn)輸入代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06