欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python動(dòng)態(tài)網(wǎng)站爬蟲(chóng)實(shí)戰(zhàn)(requests+xpath+demjson+redis)

 更新時(shí)間:2021年09月17日 08:59:00   作者:allworldg  
本文主要介紹了python動(dòng)態(tài)網(wǎng)站爬蟲(chóng)實(shí)戰(zhàn)(requests+xpath+demjson+redis),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

之前簡(jiǎn)單學(xué)習(xí)過(guò)python爬蟲(chóng)基礎(chǔ)知識(shí),并且用過(guò)scrapy框架爬取數(shù)據(jù),都是直接能用xpath定位到目標(biāo)區(qū)域然后爬取。可這次碰到的需求是爬取一個(gè)用asp.net編寫(xiě)的教育網(wǎng)站并且將教學(xué)ppt一次性爬取下來(lái),由于該網(wǎng)站部分內(nèi)容渲染采用了js,所以比較難用xpath直接定位,同時(shí)發(fā)起下載ppt的請(qǐng)求比較難找。

經(jīng)過(guò)琢磨和嘗試后爬取成功,記錄整個(gè)爬取思路供自己和大家學(xué)習(xí)。文章比較詳細(xì),對(duì)于一些工具包和相關(guān)函數(shù)的使用會(huì)在源代碼或正文中添加注釋來(lái)介紹簡(jiǎn)單相關(guān)知識(shí)點(diǎn),如果某些地方看不懂可以通過(guò)注釋及時(shí)去查閱簡(jiǎn)單了解,然后繼續(xù)閱讀。(尾部有源代碼,全文僅對(duì)一些敏感的個(gè)人信息數(shù)據(jù)進(jìn)行了省略。)

一、主要思路

1、觀察網(wǎng)站

研究從進(jìn)入網(wǎng)站到成功下載資源需要幾次url跳轉(zhuǎn)。

先進(jìn)入目標(biāo)網(wǎng)站首頁(yè),依次點(diǎn)擊教材->選擇初中->選擇教輔->選擇學(xué)科->xxx->資源列表->點(diǎn)擊下載ppt。

目標(biāo)網(wǎng)站首頁(yè)

資源列表

資源詳情頁(yè)

分析url每步跳轉(zhuǎn)以及資源下載是否需要cookie等header信息。

通過(guò)一步步跳轉(zhuǎn)進(jìn)入到最終的資源詳情頁(yè),最終點(diǎn)擊下載資源按鈕時(shí)網(wǎng)站提示并且跳轉(zhuǎn)到了登陸頁(yè)面,說(shuō)明發(fā)起下載的請(qǐng)求可能需要攜帶cookie等頭部信息。

2、編寫(xiě)爬蟲(chóng)代碼

  • 登陸賬戶(hù),獲取到識(shí)別用戶(hù)的cookies
  • 請(qǐng)求資源列表頁(yè)面,定位獲得左側(cè)目錄每一章的跳轉(zhuǎn)url。
  • 請(qǐng)求每個(gè)跳轉(zhuǎn)url,定位資源列表頁(yè)面右側(cè)下載資源按鈕的url請(qǐng)求(注意2、3步是圖資源列表)
  • 發(fā)起url請(qǐng)求,進(jìn)入資源詳情頁(yè),定位獲得下載資源按鈕的url請(qǐng)求(第4步是圖資源詳情頁(yè))
  • 發(fā)起請(qǐng)求,將下載的資源數(shù)據(jù)寫(xiě)入文件。

這是本次爬蟲(chóng)實(shí)戰(zhàn)編寫(xiě)代碼的大致思路,具體每次步驟碰到的難點(diǎn)以及如何解決在接下來(lái)的實(shí)戰(zhàn)介紹中會(huì)進(jìn)行詳細(xì)分析。

二、爬蟲(chóng)實(shí)戰(zhàn)

1、登陸獲取cookie

首先網(wǎng)站登陸,獲取到cookie和user-agent,作為之后請(qǐng)求的頭部。設(shè)置全局變量HEADER,方便調(diào)用

HEADER = {
'User-Agent':
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko)Chrome/93.0.4577.63 Safari/537.36",                                                         'Cookie':"xxxxxxx",
}

2、請(qǐng)求資源列表頁(yè)面,定位獲得左側(cè)目錄每一章的跳轉(zhuǎn)url(難點(diǎn))

首先使用requests發(fā)起資源列表頁(yè)面的請(qǐng)求

資源列表

BASE_URL = "http://www.guishiyun.com" #賦值網(wǎng)站根域名作為全局變量,方便調(diào)用

res = requests.get(BASE_URL + 
                    "/res_list.aspx?rid=9&tags=1-21,12-96,2-24,3-70",
                    headers=HEADER).text #發(fā)起請(qǐng)求,獲得資源列表頁(yè)面的html

難點(diǎn):定位獲得左側(cè)目錄每一章的跳轉(zhuǎn)url

正常思路:打開(kāi)瀏覽器控制臺(tái),查看網(wǎng)頁(yè)源代碼,尋找頁(yè)面左側(cè)課程目錄的章節(jié)在哪個(gè)元素內(nèi),用xpath定位。

使用xpath定位,發(fā)現(xiàn)無(wú)法定位到這個(gè)a標(biāo)簽,在確認(rèn)xpath語(yǔ)法無(wú)錯(cuò)誤后,嘗試打印上個(gè)代碼段中的res變量(也就是該html頁(yè)面),發(fā)現(xiàn)返回的頁(yè)面和控制臺(tái)頁(yè)面不同。

轉(zhuǎn)換思路:可能該頁(yè)面使用其他渲染方式渲染了html,導(dǎo)致瀏覽器控制臺(tái)看到的html和請(qǐng)求返回的不一樣(瀏覽器會(huì)將渲染后的頁(yè)面呈現(xiàn)),打開(kāi)控制臺(tái),查看頁(yè)面源代碼,搜素九年級(jí)上冊(cè)(左側(cè)目錄標(biāo)題),發(fā)現(xiàn)在js的script腳本中,得出該頁(yè)面應(yīng)該是通過(guò)JS渲染DOM得來(lái)的,該js對(duì)象中含有跳轉(zhuǎn)的url。

xpath行不通后,我選擇采用正則表達(dá)式的方式直接篩選出該代碼。

import re #導(dǎo)入re 正則表達(dá)式包

pattern = r'var zNodes = (\[\s*[\s\S]*\])'
#定義正則表達(dá)式,規(guī)則:找出以"var zNodes = [ \n"開(kāi)頭,含有"[多個(gè)字符或空格]"的字符,并且以"]"結(jié)尾的文本 (相關(guān)知識(shí)不熟悉的可以簡(jiǎn)單看看菜鳥(niǎo)的正則表達(dá)式)
result = re.findall(pattern, res, re.M | re.I)
#python正則表達(dá)式,查找res中符合pattern規(guī)則的文本。re.M多行匹配,re.I忽略大小寫(xiě)。

將前兩個(gè)代碼塊封裝一下

def getRootText():
    res = requests.get(BASE_URL +
                       "/res_list.aspx?rid=9&tags=1-21,12-96,2-24,3-70",
                       headers=HEADER).text #請(qǐng)求
    pattern = r'var zNodes = (\[\s*[\s\S]*\])'
    result = re.findall(pattern, res, re.M | re.I)
    return result[0] #獲得篩選結(jié)果 [{id: 1322, pI': 1122, name: '九年級(jí)上冊(cè)', open: False, url: ?catId=1322&tags=1-21%2c12-96%2c2-24%2c3-70&rid=9#bottom_content', target: '_self'}, {...},{...}]

將結(jié)果轉(zhuǎn)換成dict類(lèi)型,方便遍歷,獲得每個(gè)章節(jié)的url。瀏覽上面得出的result發(fā)現(xiàn),{id:1322,pId:xxx...}并不是標(biāo)準(zhǔn)的json格式(key沒(méi)有引號(hào)),此時(shí)使用第三方包demjson,用于將不規(guī)則的json字符串變成python的dict對(duì)象。

import demjson
def textToDict(text):
    data = demjson.decode(text)    
    #獲得篩選結(jié)果[{'id': 1322, 'pId': 1122, 'name': '九年級(jí)上冊(cè)', 'open': False, 'url': '?catId=1322&tags=1-21%2c12-96%2c2-24%2c3-70&rid=9#bottom_content', 'target': '_self'}, {...},{...}]
    return data

遍歷轉(zhuǎn)換好的dict數(shù)據(jù),獲得左側(cè)目錄每一章的url。此處需要注意的是,本人目的是下載每一章的ppt課件,所以我只需要請(qǐng)求每一個(gè)總章節(jié)的url(即請(qǐng)求第 1 章,第 2 章,不需要請(qǐng)求 1.1反比例函數(shù)),右邊就會(huì)顯示該章節(jié)下的所有ppt課件。所以我在遍歷的時(shí)候,可以通過(guò)正則表達(dá)式,篩選出符合名稱(chēng)要求的url,添加進(jìn)list并且返回。

def getUrls(dictData):
    list = []
    pattern = r'第[\s\S]*?章' #正則規(guī)則:找出以"第"開(kāi)頭,中間包含多個(gè)空格和文字,以"章"結(jié)尾的文本
    for data in dictData:	#遍歷上文轉(zhuǎn)換得到的dict數(shù)組對(duì)象
        if len(re.findall(pattern, data['name'])) != 0:
            list.append(data['url']) #如果符合則將該url添加到列表中
    return list

3、請(qǐng)求每個(gè)跳轉(zhuǎn)url,定位右側(cè)下載資源按鈕,獲得url請(qǐng)求

遍歷從上面獲得的url列表,通過(guò)拼接網(wǎng)站域名獲得網(wǎng)站url,然后發(fā)起請(qǐng)求

def download(urlList): # urlList是上面獲得的list
	for url in urlList:
        res = requests.get(BASE_URL + '/res_list.aspx/' + url, HEADER).text #完整url請(qǐng)求,獲得頁(yè)面html

查看源代碼,發(fā)現(xiàn)可以用xpath定位(目標(biāo)是獲取到onclick里的url)

分析:該按鈕元素 (<input type=button>)在<div class='res_list'><ul><li><div>里。xpath定位代碼如下:

root = etree.HTML(res) # 構(gòu)造一個(gè)xpath對(duì)象
liList = root.xpath('//div[@class="res_list"]//ul//li') #xpath語(yǔ)法,返回多個(gè)<li>及子元素對(duì)象的列表

遍歷liList ,獲得資源名字(為之后下載寫(xiě)入ppt的文件命名)以及跳轉(zhuǎn)到資源詳情下載頁(yè)的url

for li in liList:
	name = li.xpath('.//div[@class="info_area"]//div//h1//text()')
	name = name[0] # xpath返回的是包含name的列表,從中提取字符串 print(name): 1.1 反比例函數(shù)
    btnurl = li.xpath('.//div[@class="button_area"]//@onclick') # 獲得onlick內(nèi)的字符串 "window.open('res_view.aspx....')"
    pattern = r'\(\'([\s\S]*?)\'\)'# 只需要window.open內(nèi)的url,所以采用正則提取出來(lái)。
    btnurl1 = re.findall(pattern, btnurl[0])

4、跳轉(zhuǎn)到資源詳情下載頁(yè),獲得真正的下載請(qǐng)求(難點(diǎn))

上文代碼段中獲取到url之后依舊是拼接域名,然后通過(guò)完整url發(fā)起請(qǐng)求,獲得資源詳情下載頁(yè)面的html數(shù)據(jù)。

 res1 = requests.get(BASE_URL + '/' + btnurl1[0], HEADER).text

跳轉(zhuǎn)后的詳情頁(yè)面

查看源代碼后按鈕本身只是觸發(fā)表單提交,而且是post請(qǐng)求。點(diǎn)擊下載資源按鈕,使用瀏覽器控制臺(tái)抓包查看post請(qǐng)求需要的參數(shù)。

使用ctrl+f在網(wǎng)頁(yè)源代碼中搜素這幾個(gè)參數(shù),發(fā)現(xiàn)存在于<input> 標(biāo)簽中,只是被css 隱藏了,所以接下來(lái)就是簡(jiǎn)單的用xpath 和正則表達(dá)式將post請(qǐng)求中的url和這幾個(gè)參數(shù)值獲得,然后添加到header中發(fā)起請(qǐng)求就行了。

VIEWSTATE = '__VIEWSTATE'              # 全局變量,定義屬性名稱(chēng)
VIEWSTATEGENERATOR = '__VIEWSTATEGENERATOR'
EVENTVALIDATION = '__EVENTVALIDATION'
BUTTON = 'BUTTON'
BUTTON_value = '下 載 資 源'
root1 = etree.HTML(res1) # res1是之前代碼段請(qǐng)求的html文本
form = root1.xpath('//form[@id="form1"]') # xpath定位到form
action = root1.xpath('//form[@id="form1"]/@action') 
action = re.findall(r'(/[\S]*?&[\S]*?)&', action[0], re.I) #正則表達(dá)式獲取form中action函數(shù)里的url
VIEWSTATE_value = form[0].xpath(
                './/input[@name="__VIEWSTATE"]//@value') #獲取參數(shù)值
VIEWSTATEGENERATOR_value = form[0].xpath(
                './/input[@name="__VIEWSTATEGENERATOR"]//@value')#獲取參數(shù)值
EVENTVALIDATION_value = form[0].xpath(
                './/input[@name="__EVENTVALIDATION"]/@value')#獲取參數(shù)值
data = {	# post提交所需要的data參數(shù)									
          VIEWSTATE: VIEWSTATE_value,
          VIEWSTATEGENERATOR: VIEWSTATEGENERATOR_value,
          EVENTVALIDATION: EVENTVALIDATION_value,
          BUTTON: BUTTON_value
       }
res2 = requests.post(BASE_URL + action[0],data=data,headers=HEADER).text #發(fā)起請(qǐng)求

此時(shí)發(fā)起請(qǐng)求之后發(fā)現(xiàn)返回的仍然是網(wǎng)頁(yè)html,如果打開(kāi)控制臺(tái)工具,查看點(diǎn)擊按鈕發(fā)起請(qǐng)求后的頁(yè)面。

同時(shí)看到由于是更新頁(yè)面,還產(chǎn)生了許多其他各種各樣的請(qǐng)求,一時(shí)間很難找到真正下載文件的請(qǐng)求是哪一個(gè)。

此時(shí)筆者想到的是一個(gè)笨方法,通過(guò)抓包工具,對(duì)所有請(qǐng)求進(jìn)行攔截,然后一個(gè)個(gè)請(qǐng)求陸續(xù)通過(guò),最終就可以找到下載請(qǐng)求。這里筆者用到的是BurpSuite 工具,陸續(xù)放行請(qǐng)求,觀察頁(yè)面是否有下載界面出現(xiàn),找到了url:/code/down_res.ashx?id=xxx ,同時(shí)在瀏覽器控制臺(tái)查找這一串字符串,最終在post請(qǐng)求返回的頁(yè)面中找到了這個(gè)字符串的位置

不用多說(shuō),直接正則獲取

downUrl = re.search(r'\<script\>[\s]*?location\.href\s=\s\'([\S]*?)\'',res2,re.I) #正則篩選出url
 downUrl_text = downUrl.group(1)

發(fā)起請(qǐng)求,并且將數(shù)據(jù)讀寫(xiě)進(jìn)指定的目錄中。

downPPT = requests.get(BASE_URL+downUrl_text,headers=HEADER)
            with open(f'./test/{name}.ppt','wb') as f: #將下載的數(shù)據(jù)以二進(jìn)制的形式寫(xiě)入到當(dāng)前項(xiàng)目下test文件夾中,并且做好命名。name參數(shù)在上文中已經(jīng)獲得。
                f.write(downPPT.content)

結(jié)果

5、添加額外功能,實(shí)現(xiàn)增量爬蟲(chóng)

爬取到一半發(fā)現(xiàn)程序終止了,原來(lái)該網(wǎng)站對(duì)每個(gè)賬號(hào)每天下載數(shù)有限額,而我們的程序每次運(yùn)行都會(huì)從頭開(kāi)始檢索,如何對(duì)已經(jīng)爬取過(guò)的url進(jìn)行存儲(chǔ),同時(shí)下次程序運(yùn)行時(shí)對(duì)已爬取過(guò)的url進(jìn)行識(shí)別?這里筆者使用的是通過(guò)redis進(jìn)行存儲(chǔ),原理是對(duì)每次下載的url進(jìn)行存儲(chǔ),在每次發(fā)起下載請(qǐng)求時(shí)先判斷是否已經(jīng)存儲(chǔ),如果已經(jīng)存儲(chǔ)則跳過(guò)本次循環(huán)。

if(r.sadd(BASE_URL + action[0],'1')==0): # sadd是redis添加鍵值的方法,如果==0說(shuō)明已經(jīng)存在,添加失敗。
                continue

6、總源代碼

import re
import requests
from lxml import etree
import demjson
import redis

pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis('localhost',6379,decode_responses=True)


BASE_URL = "http://www.guishiyun.com"
HEADER = {
    'User-Agent':
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36",
    'Cookie':
    "xxx",
}
VIEWSTATE = '__VIEWSTATE'
VIEWSTATEGENERATOR = '__VIEWSTATEGENERATOR'
EVENTVALIDATION = '__EVENTVALIDATION'
BUTTON = 'BUTTON'
BUTTON_value = '下 載 資 源'


def getRootText():
    res = requests.get(BASE_URL +
                       "/res_list.aspx?rid=9&tags=1-21,12-96,2-24,3-70",
                       headers=HEADER).text
    pattern = r'var zNodes = (\[\s*[\s\S]*\])'
    result = re.findall(pattern, res, re.M | re.I)
    return result[0]


def textToDict(text):
    data = demjson.decode(text)
    print(data)
    return data


def getUrls(dictData):
    list = []
    pattern = r'第[\s\S]*?章'
    for data in dictData:
        if len(re.findall(pattern, data['name'])) != 0:
            list.append(data['url'])
    return list


def download(urlList):
    global r
    for url in urlList:
        res = requests.get(BASE_URL + '/res_list.aspx/' + url, HEADER).text
        root = etree.HTML(res)
        liList = root.xpath('//div[@class="res_list"]//ul//li')
        for li in liList:
            name = li.xpath('.//div[@class="info_area"]//div//h1//text()')
            name = name[0]
            btnurl = li.xpath('.//div[@class="button_area"]//@onclick')
            pattern = r'\(\'([\s\S]*?)\'\)'
            btnurl1 = re.findall(pattern, btnurl[0])
            res1 = requests.get(BASE_URL + '/' + btnurl1[0], HEADER).text
            root1 = etree.HTML(res1)
            form = root1.xpath('//form[@id="form1"]')
            action = root1.xpath('//form[@id="form1"]/@action')
            action = re.findall(r'(/[\S]*?&[\S]*?)&', action[0], re.I)
            VIEWSTATE_value = form[0].xpath(
                './/input[@name="__VIEWSTATE"]//@value')
            VIEWSTATEGENERATOR_value = form[0].xpath(
                './/input[@name="__VIEWSTATEGENERATOR"]//@value')
            EVENTVALIDATION_value = form[0].xpath(
                './/input[@name="__EVENTVALIDATION"]/@value')
            data = {
                VIEWSTATE: VIEWSTATE_value,
                VIEWSTATEGENERATOR: VIEWSTATEGENERATOR_value,
                EVENTVALIDATION: EVENTVALIDATION_value,
                BUTTON: BUTTON_value
            }
            if(r.sadd(BASE_URL + action[0],'1')==0):
                continue
            res2 = requests.post(BASE_URL + action[0],data=data,headers=HEADER).text
            downUrl = re.search(r'\<script\>[\s]*?location\.href\s=\s\'([\S]*?)\'',res2,re.I)
            downUrl_text = downUrl.group(1)
            if(r.sadd(BASE_URL+downUrl_text,BASE_URL+downUrl_text,downUrl_text)==0):
                continue
            downPPT = requests.get(BASE_URL+downUrl_text,headers=HEADER)
            with open(f'./test/{name}.ppt','wb') as f:
                f.write(downPPT.content)

def main():
    text = getRootText()
    dictData = textToDict(text)
    list = getUrls(dictData)
    # download(list)


if __name__ == '__main__':
    main()

三、總結(jié)

之前只是學(xué)習(xí)過(guò)最簡(jiǎn)單最基礎(chǔ)的requests請(qǐng)求+xpath 定位的爬蟲(chóng)方式,這次碰巧遇到了較為麻煩的爬蟲(chóng)實(shí)戰(zhàn),所以寫(xiě)下爬蟲(chóng)思路和實(shí)戰(zhàn)筆記,加深自己印象的同時(shí)也希望能對(duì)大家有所幫助。當(dāng)然這次爬蟲(chóng)總的來(lái)說(shuō)還是比較簡(jiǎn)單,還沒(méi)有考慮代理+多線程等情況,同時(shí)還可以使用selenium等瀏覽器渲染工具,就可以不用正則定位了,當(dāng)然筆者是為了順便學(xué)習(xí)一下正則。

到此這篇關(guān)于python動(dòng)態(tài)網(wǎng)站爬蟲(chóng)實(shí)戰(zhàn)(requests+xpath+demjson+redis)的文章就介紹到這了,更多相關(guān)python動(dòng)態(tài)網(wǎng)站爬蟲(chóng) 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python實(shí)現(xiàn)過(guò)迷宮小游戲示例詳解

    Python實(shí)現(xiàn)過(guò)迷宮小游戲示例詳解

    這篇文章主要介紹的是基于Python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的過(guò)迷宮小游戲,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定的幫助,感興趣的可以學(xué)習(xí)一下
    2021-12-12
  • python3 使用traceback定位異常實(shí)例

    python3 使用traceback定位異常實(shí)例

    這篇文章主要介紹了python3 使用traceback定位異常實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-03-03
  • 學(xué)python最電腦配置有要求么

    學(xué)python最電腦配置有要求么

    在本篇內(nèi)容中小編給大家整理的是關(guān)于學(xué)習(xí)python中電腦配置的相關(guān)文章,需要的朋友們可以學(xué)習(xí)下。
    2020-07-07
  • Python字符串匹配之6種方法的使用詳解

    Python字符串匹配之6種方法的使用詳解

    這篇文章主要介紹了Python字符串匹配之6種方法的使用詳解,在文末給大家提到了python正則表達(dá)的說(shuō)明,感興趣的朋友跟隨小編一起學(xué)習(xí)吧
    2019-04-04
  • python實(shí)現(xiàn)郵件自動(dòng)發(fā)送

    python實(shí)現(xiàn)郵件自動(dòng)發(fā)送

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)郵件自動(dòng)發(fā)送,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • PyTorch搭建LSTM實(shí)現(xiàn)多變量多步長(zhǎng)時(shí)序負(fù)荷預(yù)測(cè)

    PyTorch搭建LSTM實(shí)現(xiàn)多變量多步長(zhǎng)時(shí)序負(fù)荷預(yù)測(cè)

    這篇文章主要為大家介紹了PyTorch搭建LSTM實(shí)現(xiàn)多變量多步長(zhǎng)時(shí)序負(fù)荷預(yù)測(cè),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • pycharm 使用心得(九)解決No Python interpreter selected的問(wèn)題

    pycharm 使用心得(九)解決No Python interpreter selected的問(wèn)題

    PyCharm 是由JetBrains打造的一款 Python IDE。具有智能代碼編輯器,能理解 Python 的特性并提供卓越的生產(chǎn)力推進(jìn)工具:自動(dòng)代碼格式化、代碼完成、重構(gòu)、自動(dòng)導(dǎo)入和一鍵代碼導(dǎo)航等。這些功能在先進(jìn)代碼分析程序的支持下,使 PyCharm 成為 Python 專(zhuān)業(yè)開(kāi)發(fā)人員和剛起步人員使用的有力工具。
    2014-06-06
  • Python爬蟲(chóng)403錯(cuò)誤的終極解決方案

    Python爬蟲(chóng)403錯(cuò)誤的終極解決方案

    爬蟲(chóng)在爬取數(shù)據(jù)時(shí),常常會(huì)遇到"HTTP Error 403: Forbidden"的提示,其實(shí)它只是一個(gè)HTTP狀態(tài)碼,表示你在請(qǐng)求一個(gè)資源文件但是nginx不允許你查看,下面這篇文章主要給大家介紹了關(guān)于Python爬蟲(chóng)403錯(cuò)誤的終極解決方案,需要的朋友可以參考下
    2023-05-05
  • django rest framework之請(qǐng)求與響應(yīng)(詳解)

    django rest framework之請(qǐng)求與響應(yīng)(詳解)

    下面小編就為大家?guī)?lái)一篇django rest framework之請(qǐng)求與響應(yīng)(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望對(duì)大家有所幫助
    2017-11-11
  • Python實(shí)現(xiàn)基于socket的udp傳輸與接收功能詳解

    Python實(shí)現(xiàn)基于socket的udp傳輸與接收功能詳解

    這篇文章主要介紹了Python實(shí)現(xiàn)基于socket的udp傳輸與接收功能,結(jié)合實(shí)例形式詳細(xì)分析了Python使用socket進(jìn)行udp文件傳輸與接收相關(guān)操作技巧及注意事項(xiàng),需要的朋友可以參考下
    2019-11-11

最新評(píng)論