—————————如有疑問(wèn),歡迎交流指正———————— 第6關(guān) 練習(xí)-儲(chǔ)存電影信息-參考 第一步:分析問(wèn)題,明確結(jié)果 問(wèn)題需求就是把豆瓣TOP250里面的 序號(hào)/電影名/評(píng)分/推薦語(yǔ)/鏈接 都爬取下來(lái),結(jié)果是存儲(chǔ)在csv和Excel中 【講解】 問(wèn)題需求就是把豆瓣TOP250里面的 序號(hào)/電影名/評(píng)分/推薦語(yǔ)/鏈接 都爬取下來(lái),結(jié)果是存儲(chǔ)在csv和Excel中 這里拓展一下如何取標(biāo)簽???~ https:///docs/QWQJYGw8CtcwQwyq/ 《豆瓣250爬蟲(chóng)思路詳解》 第二步:書(shū)寫(xiě)爬蟲(chóng)代碼 回顧下第三關(guān)的爬蟲(chóng)代碼 【解答】 選擇語(yǔ)言 import requests,bs4
for x in range(10): headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} url = 'https://movie.douban.com/top250?start=' + str(x*25) + '&filter=' res = requests.get(url,headers=headers) bs = bs4.BeautifulSoup(res.text, 'html.parser') bs = bs.find('ol', class_='grid_view') for titles in bs.find_all('li'): num = titles.find('em',class_='').text title = titles.find('span', class_='title').text comment = titles.find('span',class_='rating_num').text url_movie = titles.find('a')['href'] if titles.find('span',class_='inq') != None: tes = titles.find('span',class_='inq').text print(num + '.' + title + '——' + comment + '\n' + '推薦語(yǔ):' + tes +'\n' + url_movie) else: print(num + '.' + title + '——' + comment + '\n' +'\n' + url_movie) 第三步: 完善代碼,用Excel存儲(chǔ)信息 要存儲(chǔ)在Excel中呢,需要先創(chuàng)建工作表,重命名,再設(shè)置表頭,把爬取的信息寫(xiě)成列表,然后用append函數(shù)多行寫(xiě)入Excel,最后命名保存這個(gè)Excel 文件。 請(qǐng)改寫(xiě)下方的爬蟲(chóng)代碼,實(shí)現(xiàn)使用Excel存儲(chǔ)信息。 【解答】 選擇語(yǔ)言 import requests, bs4, openpyxl
wb=openpyxl.Workbook() #創(chuàng)建工作薄 sheet=wb.active #獲取工作薄的活動(dòng)表 sheet.title='movies' #工作表重命名 sheet['A1'] ='序號(hào)' #加表頭,給A1單元格賦值 sheet['B1'] ='電影名' #加表頭,給B1單元格賦值 sheet['C1'] ='評(píng)分' #加表頭,給C1單元格賦值 sheet['D1'] ='推薦語(yǔ)' #加表頭,給D1單元格賦值 sheet['E1'] ='鏈接' #加表頭,給E1單元格賦值
for x in range(10): headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} url = 'https://movie.douban.com/top250?start=' + str(x*25) + '&filter=' res = requests.get(url,headers=headers) bs = bs4.BeautifulSoup(res.text, 'html.parser') bs = bs.find('ol', class_='grid_view') for titles in bs.find_all('li'): num = titles.find('em',class_='').text title = titles.find('span', class_='title').text comment = titles.find('span',class_='rating_num').text url_movie = titles.find('a')['href'] if titles.find('span',class_='inq') != None: tes = titles.find('span',class_='inq').text sheet.append([num, title, comment, tes, url_movie]) # 把num, title, comment, tes和url_movie寫(xiě)成列表,用append函數(shù)多行寫(xiě)入Excel print(num + '.' + title + '——' + comment + '\n' + '推薦語(yǔ):' + tes +'\n' + url_movie) else: sheet.append([num, title, comment, None,url_movie]) print(num + '.' + title + '——' + comment + '\n' +'\n' + url_movie) wb.save('movieTop250.xlsx') #最后保存并命名這個(gè)Excel文件 第四步:另辟蹊徑,用csv格式存儲(chǔ)信息 思考下如何用csv創(chuàng)建寫(xiě)入存儲(chǔ)呢? 請(qǐng)修改下方代碼,實(shí)現(xiàn)使用csv存儲(chǔ)信息。 【提示】 選擇語(yǔ)言 import requests, bs4, csv #引用csv模塊。 csv_file=open('movieTop250.csv', 'w', newline='') #調(diào)用open()函數(shù)打開(kāi)csv文件,傳入?yún)?shù):文件名“movieTop250.csv”、寫(xiě)入模式“w”、newline='' 【解答】 選擇語(yǔ)言 import requests, bs4, csv #引用csv模塊。 csv_file=open('movieTop250.csv', 'w', newline='') #調(diào)用open()函數(shù)打開(kāi)csv文件,傳入?yún)?shù):文件名“movieTop250.csv”、寫(xiě)入模式“w”、newline=''。 writer = csv.writer(csv_file) # 用csv.writer()函數(shù)創(chuàng)建一個(gè)writer對(duì)象。 writer.writerow(['序號(hào)', '電影名', '評(píng)分', '推薦語(yǔ)', '鏈接']) #調(diào)用writer對(duì)象的writerow()方法,可以在csv文件里寫(xiě)入title:'序號(hào)', '電影名', '評(píng)分', '推薦語(yǔ)', '鏈接'
for x in range(10): headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} url = 'https://movie.douban.com/top250?start=' + str(x*25) + '&filter=' res = requests.get(url,headers=headers) bs = bs4.BeautifulSoup(res.text, 'html.parser') bs = bs.find('ol', class_='grid_view') for titles in bs.find_all('li'): num = titles.find('em',class_='').text title = titles.find('span', class_='title').text comment = titles.find('span',class_='rating_num').text url_movie = titles.find('a')['href'] if titles.find('span',class_='inq') != None: tes = titles.find('span',class_='inq').text # 把num, title, comment, tes和url_movie寫(xiě)成列表,用append函數(shù)多行寫(xiě)入Excel writer.writerow([num + '.' + title + '——' + comment + '\n' + '推薦語(yǔ):' + tes +'\n' + url_movie]) else: writer.writerow([num + '.' + title + '——' + comment + '\n' +'\n' + url_movie]) csv_file.close() 記得出現(xiàn)亂碼的問(wèn)題,可以看這里的解決方法哦~ https:///docs/hqTrdqwQhCJGktWV/ 《爬蟲(chóng)第6關(guān)常見(jiàn)問(wèn)題解決方法》 第7關(guān) 練習(xí)-做個(gè)測(cè)單詞的小工具-參考 第一步:分析需求,明確目標(biāo) 扇貝網(wǎng):https://www./已經(jīng)有一個(gè)測(cè)單詞量的功能,我們要做的就是把這個(gè)功能復(fù)制下來(lái),并且做點(diǎn)改良,搞一個(gè)網(wǎng)頁(yè)版沒(méi)有的功能 ———— 自動(dòng)生成錯(cuò)詞本。 在這一步,請(qǐng)閱讀文檔的同時(shí)打開(kāi)瀏覽器的扇貝網(wǎng),跟著我一步步來(lái)。 【提示】 這里是扇貝網(wǎng)的測(cè)單詞量的界面: ?? 想要復(fù)制功能,就先做分析,這個(gè)網(wǎng)頁(yè)是怎樣的工作流程。 所以,先體驗(yàn)全程,大概分為如下五個(gè)頁(yè)面: ?? ?? ?? ?? ?? 先看源代碼里是否有我們的單詞。倘若有,就用find()/find_all()定位提取需要的數(shù)據(jù); 沒(méi)有的話,就要調(diào)用【檢查】-【Network】 - 【XHR】 - 找數(shù)據(jù)。 在Headers里看網(wǎng)址,在Preview里看內(nèi)容。 ?? ?? 如圖:category/這一個(gè)XHR,用的是Get請(qǐng)求方式,訪問(wèn)了網(wǎng)址https://www./api/v1/vocabtest/category/,下載了一個(gè)字典。 其中“data”里面,藏了十個(gè)元素。這十個(gè)元素,里面對(duì)應(yīng)的內(nèi)容,就是我們最開(kāi)始要選擇的“詞匯范圍”。 十個(gè)元素,每個(gè)里面都有兩個(gè)內(nèi)容。0是什么暫時(shí)還不知道,先放著。1是我們?cè)~匯范圍沒(méi)錯(cuò)。 比如我們選擇高考,那么在第2個(gè)元素里就有一個(gè)0是“NCEE”,有一個(gè)1是“高考”。 我們接著看下一個(gè)XHR: ?? 這個(gè)圖片說(shuō)明:?category=NCEE 這一個(gè)XHR,訪問(wèn)了網(wǎng)址https://www./api/v1/vocabtest/vocabularies/?category=NCEE 在此,“NCEE”出現(xiàn)了兩次:這個(gè)XHR的名字里面有“NCEE”,它訪問(wèn)的網(wǎng)址里面也有“NCEE”。 這就揭示了一種對(duì)應(yīng)關(guān)系:當(dāng)我們選擇“高考”詞庫(kù),那么下一個(gè)XHR,訪問(wèn)的網(wǎng)址就會(huì)是用“NCEE”來(lái)結(jié)尾。 可以多試幾個(gè)詞庫(kù)驗(yàn)證下我們的猜測(cè),的確里面的對(duì)應(yīng)關(guān)系是一致的??佳泻蚇GEE一組,四級(jí)和CET4一組,六級(jí)和CET6一組。 第1個(gè)XHR,所訪問(wèn)的網(wǎng)址規(guī)律就是:'https://www./api/v1/vocabtest/vocabularies/?category='+'你選擇的詞庫(kù),對(duì)應(yīng)的代碼'。 ?? 如圖,它下載到的是一個(gè)字典。字典里,包含了用來(lái)測(cè)試詞匯量的50個(gè)單詞。 第0,它先給出單詞。 第1,它給出四個(gè)不同的翻譯,每個(gè)翻譯都有一個(gè)對(duì)應(yīng)的pk值和rank值。 第2,它再給出一組pk值和rank值。它們,和正確翻譯里面的pk值與rank值一致。 那么,我們就可以理清楚,這個(gè)網(wǎng)頁(yè)的工作邏輯。如下圖: ?? 到這里,我們就完成了至關(guān)重要的“需求分析”這個(gè)步驟。 第二步:分步講解,書(shū)寫(xiě)代碼 (??????) ? ?? 【講解】 下面,我將帶你一步步完成代碼。 (0). 選擇題庫(kù)。 寫(xiě)這個(gè)程序,要用到requests模塊。 先用requests下載鏈接,再用res.json()解析下載內(nèi)容。 讓用戶選擇想測(cè)的詞庫(kù),輸入數(shù)字編號(hào),獲取題庫(kù)的代碼。 提示:記得給input前面加一個(gè)int()來(lái)轉(zhuǎn)換數(shù)據(jù)類型 【解答】 選擇語(yǔ)言 import requests
lin=requests.get('https://www./api/v1/vocabtest/category/') #先用requests下載鏈接。 js_link = lin.json() #解析下載得到的內(nèi)容。 bianhao = int(input('''請(qǐng)輸入你選擇的詞庫(kù)編號(hào),按Enter確認(rèn) 1,GMAT 2,考研 3,高考 4,四級(jí) 5,六級(jí) 6,英專 7,托福 8,GRE 9,雅思 10,任意 >''')) #讓用戶選擇自己想測(cè)的詞庫(kù),輸入數(shù)字編號(hào)。int()來(lái)轉(zhuǎn)換數(shù)據(jù)類型 ciku = js_link['data'][bianhao-1][0] print(ciku) (1). 根據(jù)選擇的題庫(kù),獲取50個(gè)單詞。 第0步我們已經(jīng)拿到鏈接,這步直接用requests去下載,re.json()解析即可。 【解答】 選擇語(yǔ)言 test = requests.get('https://www./api/v1/vocabtest/vocabularies/?category='+ciku) #下載用于測(cè)試的50個(gè)單詞。 words = test.json() #對(duì)測(cè)試的單詞進(jìn)行解析。 print(words) (2). 讓用戶選擇認(rèn)識(shí)的單詞:此處,要分別記錄下用戶認(rèn)識(shí)哪些,不認(rèn)識(shí)哪些。 已經(jīng)有了單詞數(shù)據(jù),提取出來(lái)讓用戶識(shí)別,并記錄用戶認(rèn)識(shí)哪些不認(rèn)識(shí)哪些,至少2個(gè)list來(lái)記錄。 50個(gè)單詞,記得要用循環(huán)。用戶手動(dòng)輸入自己的選擇,用input() 。我們要識(shí)別用戶的輸入,并基于此決定把這個(gè)單詞放進(jìn)哪個(gè)list,需要用if語(yǔ)句。 提示:當(dāng)一個(gè)元素特別長(zhǎng)的時(shí)候,給代碼多加一個(gè)list。 提示:加個(gè)換行,優(yōu)化用戶視角。 新增一個(gè)list,用于統(tǒng)計(jì)用戶認(rèn)識(shí)的單詞。 創(chuàng)建一個(gè)空的列表,用于記錄用戶認(rèn)識(shí)的單詞。 創(chuàng)建一個(gè)空的列表,用于記錄用戶不認(rèn)識(shí)的單詞。 啟動(dòng)一個(gè)循環(huán),循環(huán)的次數(shù)等于單詞的數(shù)量。 如果用戶認(rèn)識(shí):就把這個(gè)單詞,追加進(jìn)列表words_knows。 否則,就把這個(gè)單詞,追加進(jìn)列表not_knows。 打印一個(gè)統(tǒng)計(jì)數(shù)據(jù):這么多單詞,認(rèn)識(shí)幾個(gè),認(rèn)識(shí)的有哪些? 【解答】 選擇語(yǔ)言 danci = [] #新增一個(gè)list,用于統(tǒng)計(jì)用戶認(rèn)識(shí)的單詞 words_knows = [] not_knows = [] print ('測(cè)試現(xiàn)在開(kāi)始。如果你認(rèn)識(shí)這個(gè)單詞,請(qǐng)輸入Y,否則直接敲Enter:') n=0 for x in words['data']: n=n+1 print ('\n第'+str(n)+'個(gè):'+x['content']) #加一個(gè)\n,用于換行。 answer = input('認(rèn)識(shí)請(qǐng)敲Y,否則敲Enter:') if answer == 'Y': danci.append(x['content']) #把用戶認(rèn)識(shí)的單詞,追加進(jìn)danci這個(gè)list。 words_knows.append(x) else: not_knows.append(x)
print ('\n在上述'+str(len(words['data']))+'個(gè)單詞當(dāng)中,有'+str(len(danci))+'個(gè)是你覺(jué)得自己認(rèn)識(shí)的,它們是:') print(danci) (3). 對(duì)于用戶認(rèn)識(shí)的單詞,給選擇題讓用戶做:此處要記錄用戶做對(duì)了哪些,做錯(cuò)了哪些。 這一步是第0步和第2步的組合——涉及到第0步中的選擇,也涉及到第2步的數(shù)據(jù)記錄。 提示: 面對(duì)冗長(zhǎng)的字典列表相互嵌套,可以創(chuàng)建字典。 【解答】 選擇語(yǔ)言 print ('現(xiàn)在我們來(lái)檢測(cè)一下,你有沒(méi)有真正掌握它們:') wrong_words = [] right_num = 0 for y in words_knows: print('\n\n'+'A:'+y['definition_choices'][0]['definition']) #我們改用A、B、C、D,不再用rank值,下同 print('B:'+y['definition_choices'][1]['definition']) print('C:'+y['definition_choices'][2]['definition']) print('D:'+y['definition_choices'][3]['definition']) xuanze = input('請(qǐng)選擇單詞\''+y['content']+'\'的正確翻譯:') dic = {'A':y['definition_choices'][0]['rank'],'B':y['definition_choices'][1]['rank'],'C':y['definition_choices'][2]['rank'],'D':y['definition_choices'][3]['rank']} #我們創(chuàng)建一個(gè)字典,搭建起A、B、C、D和四個(gè)rank值的映射關(guān)系。 if dic[xuanze] == y['rank']: #此時(shí)dic[xuanze]的內(nèi)容,其實(shí)就是rank值,此時(shí)的代碼含義已經(jīng)和之前的版本相同了。 right_num += 1 else: wrong_words.append(y)
(4). 生成報(bào)告:50個(gè)單詞,不認(rèn)識(shí)多少,認(rèn)識(shí)多少,掌握多少,錯(cuò)了多少。 生成報(bào)告主要有三部分:第0,是輸出統(tǒng)計(jì)數(shù)據(jù);第1,是打印錯(cuò)題集;第2,是把錯(cuò)題集保存到本地。 【解答】 選擇語(yǔ)言 import requests
link = requests.get('https://www./api/v1/vocabtest/category/') #先用requests下載鏈接。 js_link = link.json() #解析下載得到的內(nèi)容。 bianhao = int(input('''請(qǐng)輸入你選擇的詞庫(kù)編號(hào),按Enter確認(rèn) 1,GMAT 2,考研 3,高考 4,四級(jí) 5,六級(jí) 6,英專 7,托福 8,GRE 9,雅思 10,任意 >''')) #讓用戶選擇自己想測(cè)的詞庫(kù),輸入數(shù)字編號(hào)。int()來(lái)轉(zhuǎn)換數(shù)據(jù)類型 ciku = js_link['data'][bianhao-1][0] #利用用戶輸入的數(shù)字編號(hào),獲取題庫(kù)的代碼。如果以輸入“高考”的編號(hào)“3”為例,那么ciku的值就是,在字典js_link中查找data的值,data是一個(gè)list,查找它的第bianhao-1,也就是第2個(gè)元素,得到的依然是一個(gè)list,再查找該list的第0個(gè)元素。最后得到的就是我們想要的NCEE。 test = requests.get('https://www./api/v1/vocabtest/vocabularies/?category='+ciku) #下載用于測(cè)試的50個(gè)單詞。 words = test.json() #對(duì)test進(jìn)行解析。 danci = [] #新增一個(gè)list,用于統(tǒng)計(jì)用戶認(rèn)識(shí)的單詞 words_knows = [] #創(chuàng)建一個(gè)空的列表,用于記錄用戶認(rèn)識(shí)的單詞。 not_knows = [] #創(chuàng)建一個(gè)空的列表,用于記錄用戶不認(rèn)識(shí)的單詞。 print ('測(cè)試現(xiàn)在開(kāi)始。如果你認(rèn)識(shí)這個(gè)單詞,請(qǐng)輸入Y,否則直接敲Enter:') n=0 for x in words['data']: #啟動(dòng)一個(gè)循環(huán),循環(huán)的次數(shù)等于單詞的數(shù)量。 n=n+1 print ('\n第'+str(n)+'個(gè):'+x['content']) #加一個(gè)\n,用于換行。 answer = input('認(rèn)識(shí)請(qǐng)敲Y,否則敲Enter:') #讓用戶輸入自己是否認(rèn)識(shí)。 if answer == 'Y': #如果用戶認(rèn)識(shí): danci.append(x['content']) words_knows.append(x) #就把這個(gè)單詞,追加進(jìn)列表words_knows。 else: #否則 not_knows.append(x) #就把這個(gè)單詞,追加進(jìn)列表not_knows。
print ('\n在上述'+str(len(words['data']))+'個(gè)單詞當(dāng)中,有'+str(len(danci))+'個(gè)是你覺(jué)得自己認(rèn)識(shí)的,它們是:') print(danci)
print ('現(xiàn)在我們來(lái)檢測(cè)一下,你有沒(méi)有真正掌握它們:') wrong_words = [] right_num = 0 for y in words_knows: print('\n\n'+'A:'+y['definition_choices'][0]['definition']) #我們改用A、B、C、D,不再用rank值,下同 print('B:'+y['definition_choices'][1]['definition']) print('C:'+y['definition_choices'][2]['definition']) print('D:'+y['definition_choices'][3]['definition']) xuanze = input('請(qǐng)選擇單詞\''+y['content']+'\'的正確翻譯(填寫(xiě)數(shù)字即可):') dic = {'A':y['definition_choices'][0]['rank'],'B':y['definition_choices'][1]['rank'],'C':y['definition_choices'][2]['rank'],'D':y['definition_choices'][3]['rank']} #我們創(chuàng)建一個(gè)字典,搭建起A、B、C、D和四個(gè)rank值的映射關(guān)系。 if dic[xuanze] == y['rank']: #此時(shí)dic[xuanze]的內(nèi)容,其實(shí)就是rank值,此時(shí)的代碼含義已經(jīng)和之前的版本相同了。 right_num += 1 else: wrong_words.append(y)
print ('現(xiàn)在,到了公布成績(jī)的時(shí)刻:') print ('在'+str(len(words['data']))+'個(gè)'+js_link['data'][bianhao-1][1]+'詞匯當(dāng)中,你認(rèn)識(shí)其中'+str(len(danci))+'個(gè),實(shí)際掌握'+str(right_num)+'個(gè),錯(cuò)誤'+str(len(wrong_words))+'個(gè)。') #這是句蠻復(fù)雜的話,對(duì)照前面的代碼和json文件你才能理解它。一個(gè)運(yùn)行示例是:在50個(gè)高考詞匯當(dāng)中,你認(rèn)識(shí)其中30個(gè),實(shí)際掌握25個(gè),錯(cuò)誤5個(gè)。
save = input ('是否打印并保存你的錯(cuò)詞集?填入Y或N: ') #詢問(wèn)用戶,是否要打印并保存錯(cuò)題集。 if save == 'Y': #如果用戶說(shuō)是: f = open('錯(cuò)題集.txt', 'a+') #在當(dāng)前目錄下,創(chuàng)建一個(gè)錯(cuò)題集.txt的文檔。 print ('你記錯(cuò)的單詞有:') f.write('你記錯(cuò)的單詞有:\n') #寫(xiě)入'你記錯(cuò)的單詞有:\n' m=0 for z in wrong_words: #啟動(dòng)一個(gè)循環(huán),循環(huán)的次數(shù)等于,用戶的錯(cuò)詞數(shù): m=m+1 print (z['content']) #打印每一個(gè)錯(cuò)詞。 f.write(str(m+1) +'. '+ z['content']+'\n') #寫(xiě)入序號(hào),寫(xiě)入錯(cuò)詞。 print ('你不認(rèn)識(shí)的單詞有:') f.write('你沒(méi)記住的單詞有:\n') #寫(xiě)入'你沒(méi)記住的單詞有:\n' s=0 for x in not_knows: #啟動(dòng)一個(gè)循環(huán),循環(huán)的次數(shù)等于,用戶不認(rèn)識(shí)的單詞數(shù)。 print (x['content']) #打印每一個(gè)不認(rèn)識(shí)的單詞。 f.write(str(s+1) +'. '+ x['content']+'\n') #寫(xiě)入序號(hào),寫(xiě)入用戶不認(rèn)識(shí)的詞匯。 print ('錯(cuò)詞和沒(méi)記住的詞已保存至當(dāng)前文件目錄下,下次見(jiàn)!') #告訴用戶,文件已經(jīng)保存好。 #在網(wǎng)頁(yè)版終端運(yùn)行時(shí),文件會(huì)被寫(xiě)在課程的服務(wù)器上,你看不到,但它的確已經(jīng)存在。 else: #如果用戶不想保存: print('下次見(jiàn)!') #輸出“下次見(jiàn)!” 三步:參考答案 參考答案: 選擇語(yǔ)言 import requests
link = requests.get('https://www./api/v1/vocabtest/category/') #先用requests下載鏈接。 js_link = link.json() #解析下載得到的內(nèi)容。 bianhao = int(input('''請(qǐng)輸入你選擇的詞庫(kù)編號(hào),按Enter確認(rèn) 1,GMAT 2,考研 3,高考 4,四級(jí) 5,六級(jí) 6,英專 7,托福 8,GRE 9,雅思 10,任意 >''')) #讓用戶選擇自己想測(cè)的詞庫(kù),輸入數(shù)字編號(hào)。int()來(lái)轉(zhuǎn)換數(shù)據(jù)類型 ciku = js_link['data'][bianhao-1][0] #利用用戶輸入的數(shù)字編號(hào),獲取題庫(kù)的代碼。如果以輸入“高考”的編號(hào)“3”為例,那么ciku的值就是,在字典js_link中查找data的值,data是一個(gè)list,查找它的第bianhao-1,也就是第2個(gè)元素,得到的依然是一個(gè)list,再查找該list的第0個(gè)元素。最后得到的就是我們想要的NCEE。 test = requests.get('https://www./api/v1/vocabtest/vocabularies/?category='+ciku) #下載用于測(cè)試的50個(gè)單詞。 words = test.json() #對(duì)test進(jìn)行解析。 danci = [] #新增一個(gè)list,用于統(tǒng)計(jì)用戶認(rèn)識(shí)的單詞 words_knows = [] #創(chuàng)建一個(gè)空的列表,用于記錄用戶認(rèn)識(shí)的單詞。 not_knows = [] #創(chuàng)建一個(gè)空的列表,用于記錄用戶不認(rèn)識(shí)的單詞。 print ('測(cè)試現(xiàn)在開(kāi)始。如果你認(rèn)識(shí)這個(gè)單詞,請(qǐng)輸入Y,否則直接敲Enter:') n=0 for x in words['data']: #啟動(dòng)一個(gè)循環(huán),循環(huán)的次數(shù)等于單詞的數(shù)量。 n=n+1 print ('\n第'+str(n)+'個(gè):'+x['content']) #加一個(gè)\n,用于換行。 answer = input('認(rèn)識(shí)請(qǐng)敲Y,否則敲Enter:') #讓用戶輸入自己是否認(rèn)識(shí)。 if answer == 'Y': #如果用戶認(rèn)識(shí): danci.append(x['content']) words_knows.append(x) #就把這個(gè)單詞,追加進(jìn)列表words_knows。 else: #否則 not_knows.append(x) #就把這個(gè)單詞,追加進(jìn)列表not_knows。
print ('\n在上述'+str(len(words['data']))+'個(gè)單詞當(dāng)中,有'+str(len(danci))+'個(gè)是你覺(jué)得自己認(rèn)識(shí)的,它們是:') print(danci)
print ('現(xiàn)在我們來(lái)檢測(cè)一下,你有沒(méi)有真正掌握它們:') wrong_words = [] right_num = 0 for y in words_knows: print('\n\n'+'A:'+y['definition_choices'][0]['definition']) #我們改用A、B、C、D,不再用rank值,下同 print('B:'+y['definition_choices'][1]['definition']) print('C:'+y['definition_choices'][2]['definition']) print('D:'+y['definition_choices'][3]['definition']) xuanze = input('請(qǐng)選擇單詞\''+y['content']+'\'的正確翻譯(填寫(xiě)數(shù)字即可):') dic = {'A':y['definition_choices'][0]['rank'],'B':y['definition_choices'][1]['rank'],'C':y['definition_choices'][2]['rank'],'D':y['definition_choices'][3]['rank']} #我們創(chuàng)建一個(gè)字典,搭建起A、B、C、D和四個(gè)rank值的映射關(guān)系。 if dic[xuanze] == y['rank']: #此時(shí)dic[xuanze]的內(nèi)容,其實(shí)就是rank值,此時(shí)的代碼含義已經(jīng)和之前的版本相同了。 right_num += 1 else: wrong_words.append(y)
print ('現(xiàn)在,到了公布成績(jī)的時(shí)刻:') print ('在'+str(len(words['data']))+'個(gè)'+js_link['data'][bianhao-1][1]+'詞匯當(dāng)中,你認(rèn)識(shí)其中'+str(len(danci))+'個(gè),實(shí)際掌握'+str(right_num)+'個(gè),錯(cuò)誤'+str(len(wrong_words))+'個(gè)。') #這是句蠻復(fù)雜的話,對(duì)照前面的代碼和json文件你才能理解它。一個(gè)運(yùn)行示例是:在50個(gè)高考詞匯當(dāng)中,你認(rèn)識(shí)其中30個(gè),實(shí)際掌握25個(gè),錯(cuò)誤5個(gè)。
save = input ('是否打印并保存你的錯(cuò)詞集?填入Y或N: ') #詢問(wèn)用戶,是否要打印并保存錯(cuò)題集。 if save == 'Y': #如果用戶說(shuō)是: f = open('錯(cuò)題集.txt', 'a+') #在當(dāng)前目錄下,創(chuàng)建一個(gè)錯(cuò)題集.txt的文檔。 print ('你記錯(cuò)的單詞有:') f.write('你記錯(cuò)的單詞有:\n') #寫(xiě)入'你記錯(cuò)的單詞有:\n' m=0 for z in wrong_words: #啟動(dòng)一個(gè)循環(huán),循環(huán)的次數(shù)等于,用戶的錯(cuò)詞數(shù): m=m+1 print (z['content']) #打印每一個(gè)錯(cuò)詞。 f.write(str(m+1) +'. '+ z['content']+'\n') #寫(xiě)入序號(hào),寫(xiě)入錯(cuò)詞。 print ('你不認(rèn)識(shí)的單詞有:') f.write('你沒(méi)記住的單詞有:\n') #寫(xiě)入'你沒(méi)記住的單詞有:\n' s=0 for x in not_knows: #啟動(dòng)一個(gè)循環(huán),循環(huán)的次數(shù)等于,用戶不認(rèn)識(shí)的單詞數(shù)。 print (x['content']) #打印每一個(gè)不認(rèn)識(shí)的單詞。 f.write(str(s+1) +'. '+ x['content']+'\n') #寫(xiě)入序號(hào),寫(xiě)入用戶不認(rèn)識(shí)的詞匯。 print ('錯(cuò)詞和沒(méi)記住的詞已保存至當(dāng)前文件目錄下,下次見(jiàn)!') #告訴用戶,文件已經(jīng)保存好。 #在網(wǎng)頁(yè)版終端運(yùn)行時(shí),文件會(huì)被寫(xiě)在課程的服務(wù)器上,你看不到,但它的確已經(jīng)存在。 else: #如果用戶不想保存: print('下次見(jiàn)!') #輸出“下次見(jiàn)! 第8關(guān) 練習(xí)-我家附近有啥好吃的-參考 項(xiàng)目目標(biāo):在本練習(xí),我們會(huì)借助cookies的相關(guān)知識(shí),使用Python登錄餓了么網(wǎng)站,爬取自己家附近的餐廳列表。 網(wǎng)站地址:https://www./home/ 【講解】 在本練習(xí),我們會(huì)借助cookies的相關(guān)知識(shí),使用Python登錄餓了么網(wǎng)站,爬取自己家附近的餐廳。 網(wǎng)站地址:https://www./home/ 想要順利地爬取餓了么上面的餐廳列表,我們需要先自己前往餓了么網(wǎng)站,手動(dòng)找到餐廳列表所在位置。然后,再用Python代碼去模擬這個(gè)過(guò)程。 首先,打開(kāi)餓了么首頁(yè):(https://www./home/) 打開(kāi)【檢查】工具,選擇【Network】,勾選【Preserve log】(因?yàn)榈葧?huì)可能會(huì)有頁(yè)面跳轉(zhuǎn),勾選上防止在跳轉(zhuǎn)過(guò)程中請(qǐng)求被清空)。 ?? 然后,輸入地址,如:“騰訊大廈”(推薦先把文字打好,再利用復(fù)制粘貼一次性輸入,不要一個(gè)字一個(gè)字填輸),頁(yè)面會(huì)彈出許多個(gè)地址給你選擇。此刻,會(huì)看到右側(cè)的Network面板里多出一個(gè)XHR:pois?…… 這說(shuō)明,這些地址列表和XHR之間存在有對(duì)應(yīng)關(guān)系。記住這個(gè)XHR,它很重要,后面會(huì)用到。 我們先點(diǎn)擊一個(gè)地址,比如我選擇的第0個(gè),“騰訊大廈”,它會(huì)跳轉(zhuǎn)至一個(gè)新地址:(https://www./place/ws100xkkpznf?latitude=22.54055&longitude=113.934401) ?? 此時(shí),頁(yè)面要求我們登錄。我們點(diǎn)擊登錄,會(huì)來(lái)到(https://h5.ele.me/login/#redirect=https%3A%2F%2Fwww.%2Fplace%2Fws100xkkpznf%3Flatitude%3D22.54055%26longitude%3D113.934401) ?? 閱讀該URL,很容易能夠看出這個(gè)是一個(gè)登錄頁(yè),因?yàn)橛衛(wèi)ogin存在。同時(shí)它在?之后所攜帶的參數(shù),含義是來(lái)源:我們剛剛從哪個(gè)URL跳轉(zhuǎn)過(guò)來(lái)。 輸入手機(jī)號(hào)碼,點(diǎn)擊收取驗(yàn)證碼,此時(shí)瀏覽器會(huì)發(fā)起請(qǐng)求:mobile_send_code。 手機(jī)收到驗(yàn)證碼,輸入驗(yàn)證碼,完成登錄。頁(yè)面會(huì)重新跳轉(zhuǎn)回我們剛剛來(lái)到的地址,此時(shí)的頁(yè)面,出現(xiàn)了我們想要的餐館名。 ?? login_by_mobile即是登錄獲取cookies的那個(gè)請(qǐng)求。 通過(guò)翻找Network,我們定位到,存儲(chǔ)有餐廳列表的請(qǐng)求是XHR:restaurants… 該請(qǐng)求需要若干參數(shù),如下: 1. extras[]:activities 2. geohash:通過(guò)搜索得之,這是一個(gè)能夠代表地理位置的字符串。 3. latitude:緯度 4. limit:一次加載多少個(gè)餐館 5. longitude:經(jīng)度 6. offset:起始值 7. terminal: web 思考實(shí)現(xiàn)方案 這個(gè)網(wǎng)站,要求登錄才能實(shí)現(xiàn)爬取餐館列表。所以我們需要用到cookies來(lái)實(shí)現(xiàn)。 所以理論上,我們的代碼順序應(yīng)該是:模擬登錄獲取cookies,再帶著cookies去請(qǐng)求餐館列表。 不過(guò),必須要指出的是。請(qǐng)求餐館列表,還需要一些參數(shù)才行。這些參數(shù),和我們剛剛在首頁(yè)輸入“騰訊大廈”四個(gè)字的操作有關(guān)。 具體,我們?cè)谧龃a實(shí)操時(shí)再展開(kāi)講解。 所以正確的過(guò)程應(yīng)該是: - 模擬登錄獲取cookies - 模擬輸入“騰訊大廈”獲取必要的參數(shù) - 帶著參數(shù)和cookies,去請(qǐng)求餐館列表 其中,前兩步可以順序調(diào)換。 【講解】 下面,我將帶你一步步完成代碼。 一、使用session和cookies模擬登錄 體驗(yàn)登錄:https://h5./login/ 提示:此處需要先模擬發(fā)送驗(yàn)證碼的請(qǐng)求,再模擬登錄的請(qǐng)求。 提示:請(qǐng)求驗(yàn)證碼時(shí),會(huì)返回一個(gè)json,json里會(huì)有validate_token。它在我們輸入賬號(hào)驗(yàn)證碼模擬登錄的時(shí)候,會(huì)用到。 模擬登錄參考示例: 選擇語(yǔ)言 import requests session = requests.session() #創(chuàng)建會(huì)話。 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } #添加請(qǐng)求頭,避免被反爬蟲(chóng)。 url = ' https://wordpress-edu-3autumn.localprod./wp-login.php' #登錄的網(wǎng)址。 data = {'log': input('請(qǐng)輸入你的賬號(hào):'), 'pwd': input('請(qǐng)輸入你的密碼:'), 'wp-submit': '登錄', 'redirect_to': 'https://wordpress-edu-3autumn.localprod./wp-admin/', 'testcookie': '1'} #登錄的參數(shù)。 session.post(url, headers=headers, data=data) #在會(huì)話下,用post發(fā)起登錄請(qǐng)求。 【解答】 選擇語(yǔ)言 import requests session = requests.session() # 創(chuàng)建會(huì)話 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } # 添加請(qǐng)求頭,避免被反爬蟲(chóng) url_1 = 'https://h5./restapi/eus/login/mobile_send_code' # 發(fā)送驗(yàn)證碼的網(wǎng)址 tel = input('請(qǐng)輸入手機(jī)號(hào)碼:') data_1 = {'captcha_hash':'', 'captcha_value':'', 'mobile':tel, 'scf':''} # 發(fā)送驗(yàn)證碼的參數(shù) token = session.post(url_1, headers=headers, data=data_1).json()['validate_token'] # 在會(huì)話下,模擬獲取驗(yàn)證碼的請(qǐng)求
url_2 = 'https://h5./restapi/eus/login/login_by_mobile' code = input('請(qǐng)輸入手機(jī)驗(yàn)證碼:') data_2 = {'mobile':tel, 'scf':'ms', 'validate_code':code, 'validate_token':token} session.post(url_2,headers=headers,data=data_2) 二、模擬輸入地址,獲取必要參數(shù) 為了請(qǐng)求餐館列表,我們需要幾個(gè)關(guān)鍵參數(shù): 1. geohash:通過(guò)搜索得之,這是一個(gè)能夠代表地理位置的字符串。 2. latitude:緯度 3. longitude:經(jīng)度 這三個(gè)參數(shù),都需要模擬輸入地址來(lái)獲得。請(qǐng)打印出這三個(gè)參數(shù)。 體驗(yàn)輸入地址:https://www./home/ 提示:本步驟不需要模擬登錄 提示:在模擬該請(qǐng)求時(shí)需要用到城市的geohash值,可在XHR里查看自己城市的geohash值 【解答】 選擇語(yǔ)言 import requests # 導(dǎo)入requests模塊。 address_url = 'https://www./restapi/v2/pois?' # 你能夠在【Headers】-【General】里找到這個(gè)鏈接。 place = input('請(qǐng)輸入你的收貨地址:') # 使用input輸入收獲地址,賦值給place。 # 因?yàn)槲覀兊膅eohash使用了深圳的值,所以推薦你測(cè)試的時(shí)候使用“騰訊大廈”。 params = {'extras[]':'count','geohash':'ws105rz9smwm','keyword':place,'limit':'20','type':'nearby'} # 將要傳遞的參數(shù)封裝成字典,鍵與值都要用字符串,其中keyword對(duì)于的值是place。 address_res = requests.get(address_url,params=params) # 發(fā)起請(qǐng)求,將響應(yīng)的結(jié)果,賦值給address_res address_json = address_res.json() # 將響應(yīng)的結(jié)果轉(zhuǎn)為列表/字典。
print('以下,是與'+place+'相關(guān)的位置信息:\n') n=0 # 添加一個(gè)計(jì)數(shù)器,作為序號(hào)。 for address in address_json: # 遍歷我們剛爬取的地址列表。 print(str(n)+'. '+address['name']+':'+address['short_address']+'\n') # 打印序號(hào),地址名,短地址。 n = n+1 # 給計(jì)數(shù)器加1。 address_num = int(input('請(qǐng)輸入您選擇位置的序號(hào):')) # 讓用戶選擇序號(hào)。 final_address = address_json[address_num] # 確認(rèn)地址。
print(final_address['geohash']) print(final_address['latitude']) print(final_address['longitude']) 三、帶cookies和參數(shù)請(qǐng)求餐館列表 最后一步,將上述兩組代碼組合。 拿到cookies和參數(shù),完成請(qǐng)求餐館列表。 我?guī)湍泐A(yù)置了前兩個(gè)代碼,你可以在此基礎(chǔ)上完成本關(guān)卡任務(wù)。 【解答】 選擇語(yǔ)言 import requests session = requests.session()
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } url_1 = 'https://h5./restapi/eus/login/mobile_send_code' tel = input('請(qǐng)輸入手機(jī)號(hào)碼:') data_1 = {'captcha_hash':'', 'captcha_value':'', 'mobile':tel, 'scf':''}
token = session.post(url_1, headers=headers, data=data_1).json()['validate_token']
url_2 = 'https://h5./restapi/eus/login/login_by_mobile' code = input('請(qǐng)輸入手機(jī)驗(yàn)證碼:') data_2 = {'mobile':tel, 'scf':'ms', 'validate_code':code, 'validate_token':token}
session.post(url_2,headers=headers,data=data_2)
address_url = 'https://www./restapi/v2/pois?' place = input('請(qǐng)輸入你的收貨地址:') params = {'extras[]':'count','geohash':'ws105rz9smwm','keyword':place,'limit':'20','type':'nearby'} # 這里使用了深圳的geohash
address_res = requests.get(address_url,params=params) address_json = address_res.json()
print('以下,是與'+place+'相關(guān)的位置信息:\n') n=0 for address in address_json: print(str(n)+'. '+address['name']+':'+address['short_address']+'\n') n = n+1 address_num = int(input('請(qǐng)輸入您選擇位置的序號(hào):')) final_address = address_json[address_num]
restaurants_url = 'https://www./restapi/shopping/restaurants?' # 使用帶有餐館列表的那個(gè)XHR地址。 params = {'extras[]':'activities', 'geohash':final_address['geohash'], 'latitude':final_address['latitude'], 'limit':'24', 'longitude':final_address['longitude'], 'offset':'0', 'terminal':'web' } # 將參數(shù)封裝,其中g(shù)eohash和經(jīng)緯度,來(lái)自前面獲取到的數(shù)據(jù)。 restaurants_res = session.get(restaurants_url,params=params) # 發(fā)起請(qǐng)求,將響應(yīng)的結(jié)果,賦值給restaurants_res restaurants = restaurants_res.json() # 把response對(duì)象,轉(zhuǎn)為json。 for restaurant in restaurants: # restsurants最外層是一個(gè)列表,它可被遍歷。restaurant則是字典,里面包含了單個(gè)餐廳的所有信息。 print(restaurant['name']) 參考答案和總結(jié) 參考答案: 選擇語(yǔ)言 import requests session = requests.session()
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } url_1 = 'https://h5./restapi/eus/login/mobile_send_code' tel = input('請(qǐng)輸入手機(jī)號(hào)碼:') data_1 = {'captcha_hash':'', 'captcha_value':'', 'mobile':tel, 'scf':''}
token = session.post(url_1, headers=headers, data=data_1).json()['validate_token']
url_2 = 'https://h5./restapi/eus/login/login_by_mobile' code = input('請(qǐng)輸入手機(jī)驗(yàn)證碼:') data_2 = {'mobile':tel, 'scf':'ms', 'validate_code':code, 'validate_token':token}
session.post(url_2,headers=headers,data=data_2)
address_url = 'https://www./restapi/v2/pois?' place = input('請(qǐng)輸入你的收貨地址:') params = {'extras[]':'count','geohash':'ws105rz9smwm','keyword':place,'limit':'20','type':'nearby'} # 這里使用了深圳的geohash
address_res = requests.get(address_url,params=params) address_json = address_res.json()
print('以下,是與'+place+'相關(guān)的位置信息:\n') n=0 for address in address_json: print(str(n)+'. '+address['name']+':'+address['short_address']+'\n') n = n+1 address_num = int(input('請(qǐng)輸入您選擇位置的序號(hào):')) final_address = address_json[address_num]
restaurants_url = 'https://www./restapi/shopping/restaurants?' # 使用帶有餐館列表的那個(gè)XHR地址。 params = {'extras[]':'activities', 'geohash':final_address['geohash'], 'latitude':final_address['latitude'], 'limit':'24', 'longitude':final_address['longitude'], 'offset':'0', 'terminal':'web' } # 將參數(shù)封裝,其中g(shù)eohash和經(jīng)緯度,來(lái)自前面獲取到的數(shù)據(jù)。 restaurants_res = session.get(restaurants_url,params=params) # 發(fā)起請(qǐng)求,將響應(yīng)的結(jié)果,賦值給restaurants_res restaurants = restaurants_res.json() # 把response對(duì)象,轉(zhuǎn)為json。 for restaurant in restaurants: # restsurants最外層是一個(gè)列表,它可被遍歷。restaurant則是字典,里面包含了單個(gè)餐廳的所有信息。 print(restaurant['name']) 下面講一下會(huì)遇到的問(wèn)題~ validate_token這個(gè)在哪里可以找到呢? ?? 輸入手機(jī)號(hào)碼,點(diǎn)擊獲取 驗(yàn)證碼后,在文件mobile_send_code的Preview里面 ?? 出現(xiàn)這樣的錯(cuò)誤keyerror:validate_token 或者:{'message': '賬戶存在風(fēng)險(xiǎn),需要圖形驗(yàn)證碼', 'name': 'NEED_CAPTCHA'} ?? 出現(xiàn)這個(gè)問(wèn)題一般ip請(qǐng)求多次,一般第4次后,就可能引起餓了么的反爬機(jī)制,導(dǎo)致出現(xiàn)你的訪問(wèn)異常,結(jié)果是keyerror錯(cuò)誤;也就是需要圖形驗(yàn)證碼; 在山腰的知識(shí)暫時(shí)是無(wú)法解決的,目前可以每天嘗試幾次,或者換個(gè)手機(jī)或者ip網(wǎng)絡(luò);例如熱點(diǎn);建議出現(xiàn)keyerror可以暫時(shí)運(yùn)行跳過(guò),后續(xù)再試;一天一般有3-4次機(jī)會(huì) 如果要通過(guò)圖片驗(yàn)證,一般主流有4種方法: 1)打碼平臺(tái)付費(fèi)打碼 2)PIL庫(kù)提取圖片文字 3)第9關(guān)的selenium模擬 選擇語(yǔ)言 import requests headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'} def get_picture(): url = 'https://h5./restapi/eus/v3/captchas' param = {'captcha_str':input('手機(jī)號(hào)碼')} res = requests.get(url,params=param).json()['captcha_image'] import time from selenium import webdriver driver = webdriver.Chrome() driver.get(res) time.sleep(5) 4)get_picture() 找到圖片驗(yàn)證碼在network里的位置,像爬圖片一樣保存到本地,然后input模擬輸入驗(yàn)證碼 (*在網(wǎng)頁(yè)中輸入手機(jī)號(hào),需要輸入驗(yàn)證碼,在network里的img里找到驗(yàn)證碼所在的圖片,在像第0關(guān)教的爬取圖片一樣爬到本地展示,在模擬input輸入) 選擇語(yǔ)言 import requests url = 'https://h5./restapi/eus/v3/captchas' headers = { 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', 'cookie': 'ubt_ssid=tita2xpcvoy6tbuzvwldp2tng4pz58l3_2019-04-28; _utrace=c2afcac7405b5632ba7a2987726b2cb4_2019-04-28; perf_ssid=e6xbec0ng906g0vof33vdf0vyrqgvts7_2019-04-28; UTUSER=0; cna=nawpFbIGrU8CAbcPsMlh4vqb; isg=BB0dLMZEHXmoNPlVLI0iBcyJLPkdMlOxf7IvI9_iInSjlj7Iq4jmXbNAwMo1VmlE', } captian = requests.get(url,headers=headers).json() print(captian['captcha_image']) 補(bǔ)充:餓了么實(shí)現(xiàn)的參考博客 https://blog.csdn.net/weixin_43868179/article/details/94377658 餓了嗎里面那個(gè)查詢地址的鏈接是在哪找到的? ?? 餓了么搜索地址的請(qǐng)求里url做了修改,練習(xí)時(shí)以網(wǎng)頁(yè)上實(shí)際的情況為準(zhǔn) ?? 一份總結(jié): 就是這樣一個(gè)代碼,它能拿到給定位置附近的餐廳名。但它的潛力并不只是如此。 如果我們嘗試加載餓了么官網(wǎng)的首頁(yè),能夠找到一個(gè)xhr叫做cities,這個(gè)xhr里包含了全國(guó)兩千多個(gè)城市的經(jīng)緯度。 利用Python的geohash模塊,你可以將經(jīng)緯度數(shù)據(jù),轉(zhuǎn)化為geohash(當(dāng)然,也可以將geohash轉(zhuǎn)為經(jīng)緯度,我也是用這種方式,發(fā)現(xiàn)我的默認(rèn)geohash是深圳)。 那么在理論上,其實(shí)你可以通過(guò)這種方式,拿到全國(guó)餐廳的數(shù)據(jù)…… 只要稍做擴(kuò)展,它還能拿到許多數(shù)據(jù):所有的餐廳名/電話號(hào)碼/評(píng)分/品牌/經(jīng)緯度/介紹/均價(jià)/月銷量…… 此時(shí),這個(gè)爬蟲(chóng)就具備了商業(yè)價(jià)值,它能勝任許多數(shù)據(jù)分析的工作:選址策略、定價(jià)策略、差異化競(jìng)爭(zhēng)、2B營(yíng)銷…… 或許你會(huì)質(zhì)疑自己能不能做到像我描述的這樣厲害,不用怕,很快你就能夠做到對(duì)此心中有數(shù)。 而在后續(xù)的關(guān)卡,當(dāng)你學(xué)會(huì)反爬蟲(chóng)的應(yīng)對(duì)策略、協(xié)程、Scrapy框架……你會(huì)變得像我說(shuō)的那樣強(qiáng)大。 新練習(xí)-大神快更文 ?? 困難(#fb5a5c)
cookies與session post與get json數(shù)據(jù)解析與提取 反爬蟲(chóng)應(yīng)對(duì)策略
要求: 在本練習(xí),我們會(huì)借助cookies的相關(guān)知識(shí),使用Python登錄小說(shuō)網(wǎng)站,用代碼的形式對(duì)熱榜上的大神進(jìn)行催更。 網(wǎng)站地址:https://www./ 目的: - 練習(xí)掌握cookies和session的用法
- 練習(xí)post和get請(qǐng)求
- 練習(xí)json數(shù)據(jù)的解析提取
- 反爬蟲(chóng)應(yīng)對(duì)策略
知識(shí)點(diǎn)回顧 cookies與session cookies是服務(wù)器為了標(biāo)記用戶,存儲(chǔ)在用戶本地的數(shù)據(jù),它里面也保存了用戶的登錄信息,同時(shí)它有一定的時(shí)效性,過(guò)期就會(huì)失效。 ?? session是會(huì)話過(guò)程中,服務(wù)器用來(lái)記錄特定用戶會(huì)話的信息。 ?? session和cookies的關(guān)系:cookies里帶有session的編碼信息,服務(wù)器可以通過(guò)cookies辨別用戶,同時(shí)返回和這個(gè)用戶相關(guān)的特定編碼的session。 ?? ?? ?? 代碼示例如下: 選擇語(yǔ)言 import requests,json session = requests.session() #創(chuàng)建會(huì)話。 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } #添加請(qǐng)求頭,避免被反爬蟲(chóng)。 try: #如果能讀取到cookies文件,執(zhí)行以下代碼,跳過(guò)except的代碼,不用登錄就能發(fā)表評(píng)論。 cookies_txt = open('cookies.txt', 'r') #以reader讀取模式,打開(kāi)名為cookies.txt的文件。 cookies_dict = json.loads(cookies_txt.read()) #調(diào)用json模塊的loads函數(shù),把字符串轉(zhuǎn)成字典。 cookies = requests.utils.cookiejar_from_dict(cookies_dict) #把轉(zhuǎn)成字典的cookies再轉(zhuǎn)成cookies本來(lái)的格式。 session.cookies = cookies #獲取會(huì)話下的cookies
except FileNotFoundError: #如果讀取不到cookies文件,程序報(bào)“FileNotFoundError”(找不到文件)的錯(cuò),則執(zhí)行以下代碼,重新登錄獲取cookies,再評(píng)論。
url = 'https://wordpress-edu-3autumn.localprod.oc.forchange.cn/wp-login.php' #登錄的網(wǎng)址。 data = {'log': input('請(qǐng)輸入你的賬號(hào):'), 'pwd': input('請(qǐng)輸入你的密碼:'), 'wp-submit': '登錄', 'redirect_to': 'https://wordpress-edu-3autumn.localprod./wp-admin/', 'testcookie': '1'} #登錄的參數(shù)。 session.post(url, headers=headers, data=data) #在會(huì)話下,用post發(fā)起登錄請(qǐng)求。
cookies_dict = requests.utils.dict_from_cookiejar(session.cookies) #把cookies轉(zhuǎn)化成字典。 cookies_str = json.dumps(cookies_dict) #調(diào)用json模塊的dump函數(shù),把cookies從字典再轉(zhuǎn)成字符串。 f = open('cookies.txt', 'w') #創(chuàng)建名為cookies.txt的文件,以寫(xiě)入模式寫(xiě)入內(nèi)容 f.write(cookies_str) #把已經(jīng)轉(zhuǎn)成字符串的cookies寫(xiě)入文件 f.close() #關(guān)閉文件
url_1 = 'https://wordpress-edu-3autumn.localprod./wp-comments-post.php' #文章的網(wǎng)址。 data_1 = { 'comment': input('請(qǐng)輸入你想評(píng)論的內(nèi)容:'), 'submit': '發(fā)表評(píng)論', 'comment_post_ID': '13', 'comment_parent': '0' } #評(píng)論的參數(shù)。 session.post(url_1, headers=headers, data=data_1) #在會(huì)話下,用post發(fā)起評(píng)論請(qǐng)求。 post與get post和get都可以帶著參數(shù)請(qǐng)求,不過(guò)get請(qǐng)求的參數(shù)會(huì)在url上顯示出來(lái)。但post請(qǐng)求的參數(shù)就不會(huì)直接顯示,而是隱藏起來(lái)。 在post請(qǐng)求里,我們使用data來(lái)傳遞參數(shù),其用法和params非常相像。 代碼示例: 選擇語(yǔ)言 import requests
url_1 = 'https://…' headers = {'user-agent':''} data = {} # 定義url,headers和data
login_in = requests.post(url,headers=headers,data=data) cookies = login_in.cookies # 完成登錄,獲取cookies
url_2 = 'https://…' params = {} # 定義url和params
response = requests.get(url,headers=headers,params=params,cookies=cookies) # 帶著cookies重新發(fā)起請(qǐng)求 步驟 題目要求 項(xiàng)目目標(biāo):在本練習(xí),我們會(huì)借助cookies的相關(guān)知識(shí),使用Python登錄小說(shuō)樓,爬取熱榜小說(shuō),對(duì)作者進(jìn)行催更。 網(wǎng)站地址:https://www./ 【講解】 在本練習(xí),我們會(huì)借助cookies的相關(guān)知識(shí),使用Python登錄小說(shuō)樓,爬取熱榜小說(shuō),對(duì)作者進(jìn)行催更。 網(wǎng)站地址:https://www./ 分步講解 在這一步,我會(huì)帶領(lǐng)你完成“分析過(guò)程”,請(qǐng)務(wù)必完整閱讀文檔。 在下一步,我們會(huì)開(kāi)始按步驟書(shū)寫(xiě)代碼。 【講解】 體驗(yàn)流程 想要對(duì)熱榜的小說(shuō)進(jìn)行催更,我們首先需要用瀏覽器體驗(yàn)這個(gè)過(guò)程。 前往小說(shuō)樓,手動(dòng)找到熱榜所在位置 - 隨機(jī)對(duì)一部小說(shuō)進(jìn)行催更
- 最后,再用Python代碼去模擬這個(gè)過(guò)程
進(jìn)入熱榜 首先,打開(kāi)小說(shuō)樓的排行榜頁(yè):https://www./top/allvisit_1/ 打開(kāi)【檢查】工具,選擇【Network】,勾選【Preserve log】(因?yàn)榈葧?huì)可能會(huì)有頁(yè)面跳轉(zhuǎn),勾選上防止在跳轉(zhuǎn)過(guò)程中請(qǐng)求被清空)。 { 【新增圖片】 【原圖鏈接:】?? 【原來(lái)的樣式:】?? 【0】鼠標(biāo)右鍵選中下拉菜單的“檢查” 【1】選擇Network 【2】勾選Preserve log ?? 體驗(yàn)登錄 1、然后我們可以隨機(jī)點(diǎn)擊其中一本小說(shuō),對(duì)其進(jìn)行催更 (現(xiàn)在網(wǎng)頁(yè)更新,已經(jīng)沒(méi)有催更功能了!建議同學(xué)們直接用下載小說(shuō)來(lái)做練習(xí)) ?? ?? 2、此時(shí),如果沒(méi)有登錄小說(shuō)樓(或注冊(cè))的用戶,會(huì)自動(dòng)跳到小說(shuō)樓的登錄頁(yè)面:https://www./login.php 也就是說(shuō),想要催更,我們必須通過(guò)登錄呀~(模擬登陸?。?!催更的步驟先不做?。?/span> ?? 3、閱讀該URL,很容易能夠看出這個(gè)是一個(gè)登錄頁(yè),因?yàn)橛墟溄佑袀€(gè)login(中文:登錄) 4、輸入賬號(hào)和密碼,同時(shí)查看Network,便會(huì)發(fā)現(xiàn)瀏覽器會(huì)攜帶著賬號(hào)和密碼發(fā)起Post請(qǐng)求。 { 【新增圖片】 【原圖鏈接:】?? ?? 獲取催更鏈接(換成下載小說(shuō)鏈接) 1、完成登錄之后,頁(yè)面會(huì)跳轉(zhuǎn)到催更的頁(yè)面,提示催更成功 ?? 通過(guò)翻找Network,我們定位到,催更的請(qǐng)求是就是當(dāng)前的url:https://www./modules/article/usercui.php?id=xxx { 【新增圖片】 【原圖鏈接:】?? } ?? 該請(qǐng)求只需要一個(gè)參數(shù):id(書(shū)籍的id) 注意:該鏈接限制了每天催更不能超過(guò)5次,也就是說(shuō)該鏈接的請(qǐng)求不能超過(guò)5次 獲取書(shū)籍id 1、進(jìn)入小說(shuō)熱門列表頁(yè)面:https://www./top/allvisit_1/右鍵檢查, 發(fā)現(xiàn)該頁(yè)面的數(shù)據(jù)就在第0個(gè)請(qǐng)求當(dāng)中。 2、模擬催更書(shū)籍《純陽(yáng)武神》時(shí),拿到的id是9356, 不過(guò)這個(gè)id到底從哪里來(lái)的? 要么,它藏在了HTML網(wǎng)頁(yè)當(dāng)中; 要么,它就是在請(qǐng)求的時(shí)候,后臺(tái)下發(fā)的。 可先在Elements搜索一下該id,看它在不在HTML里。 (【搜索快捷鍵】win:ctrl+f | mac:command+f) { 【新增圖片】 【原圖鏈接:】??} ?? 3、經(jīng)過(guò)分析,發(fā)現(xiàn)id確實(shí)藏在了HTML頁(yè)面的鏈接當(dāng)中:https://www./yuedu/9356/ 4、下一步就是將數(shù)字9356從鏈接中分離出來(lái),方法有很多,老師這里只講解過(guò)濾器fliter過(guò)濾數(shù)字 選擇語(yǔ)言 link = 'https://www./yuedu/9356/'
# 字符串link過(guò)濾出數(shù)字id(9356) id_list = list(filter(str.isdigit,link)) book_id = ''.join(book_id)
# 步驟解析:1、filter()過(guò)濾數(shù)字 2、filter對(duì)象轉(zhuǎn)列表 3、列表轉(zhuǎn)字符串 # filter(str.isdigit,字符串) # 第一個(gè)參數(shù)用來(lái)判斷字符串的單個(gè)元素是否是數(shù)字,數(shù)字保留 # filter()返回的是對(duì)象,需要用list()函數(shù)轉(zhuǎn)換成列表 # ''.join(列表)將列表轉(zhuǎn)換成字符串 思考實(shí)現(xiàn)方案 所以正確的流程應(yīng)該是: - 使用id參數(shù)和cookies請(qǐng)求催更
注:其中,前兩步可以順序調(diào)換。 代碼實(shí)現(xiàn) 【講解】 下面,我將帶你一步步完成代碼。 一、使用session和cookies模擬登錄 體驗(yàn)登錄:https://www./login.php 模擬登錄參考示例: 選擇語(yǔ)言 import requests
# 創(chuàng)建會(huì)話。 session = requests.session() # 添加請(qǐng)求頭,避免被反爬蟲(chóng)。 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' }
# 登錄的網(wǎng)址。 url = ' https://wordpress-edu-3autumn.localprod.oc.forchange.cn/wp-login.php' # 登錄的參數(shù)。 data = {'log': input('請(qǐng)輸入你的賬號(hào):'), 'pwd': input('請(qǐng)輸入你的密碼:'), 'wp-submit': '登錄', 'redirect_to': 'https://wordpress-edu-3autumn.localprod./wp-admin/', 'testcookie': '1'}
#在會(huì)話下,用post發(fā)起登錄請(qǐng)求。 session.post(url, headers=headers, data=data) 【代碼題】 【預(yù)設(shè)代碼】 # 小說(shuō)樓登錄請(qǐng)求:https://www./login.php 【解答】 選擇語(yǔ)言 import requests
# 創(chuàng)建會(huì)話 session = requests.session() # 偽裝請(qǐng)求頭 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } # 登錄url login_url = 'https://www./login.php' # 登錄的參數(shù)。 data = {'username':input('請(qǐng)輸入你的賬號(hào):'), 'password':input('請(qǐng)輸入你的密碼:'), 'action':'login'} result = session.post(login_url, headers=headers, data=data) 二、獲取書(shū)籍id 想要請(qǐng)求催更XHR,我們需要拿到參數(shù)id,也就是書(shū)籍id 小說(shuō)排行榜:https://www./top/allvisit_1/ 提示1: 1. 本步驟不需要模擬登錄 2. 網(wǎng)站的編碼模式是gbk 提示2: 選擇語(yǔ)言 link = 'https://www./yuedu/9356/'
# 字符串link過(guò)濾出數(shù)字id(9356) id_list = list(filter(str.isdigit,link)) book_id = ''.join(book_id)
# 步驟解析:1、filter()過(guò)濾數(shù)字 2、filter對(duì)象轉(zhuǎn)列表 3、列表轉(zhuǎn)字符串 # filter(str.isdigit,字符串) # 第一個(gè)參數(shù)用來(lái)判斷字符串的單個(gè)元素是否是數(shù)字,數(shù)字保留 # filter()返回的是對(duì)象,需要用list()函數(shù)轉(zhuǎn)換成列表 # ''.join(列表)將列表轉(zhuǎn)換成字符串 提示3: 選擇語(yǔ)言 # 爬取鏈接html頁(yè)面中a標(biāo)簽的鏈接以及內(nèi)容 import requests from bs4 import BeautifulSoup
url = 'https://movie.douban.com/top250?start=25&filter=' results = requests.get(url) results.encoding = 'utf8' bs = BeautifulSoup(results.text,'html.parser') ols = bs.find('ol',class_='grid_view') for ls in ols.find_all('li'): url_movie = ls.find('a')['href'] url_text = ls.find('a').text 【代碼題】 【預(yù)設(shè)代碼】 # 本步驟不需要模擬登錄 # 小說(shuō)樓的排行榜:https://www./top/allvisit_1/ 【解答】 選擇語(yǔ)言
import requests from bs4 import BeautifulSoup
hot_url = 'https://www./top/allvisit_1/' r = requests.get(hot_url) r.encoding = 'gbk' bs = BeautifulSoup(r.text,'html.parser') uls = bs.find_all('span',class_='up2') books = {} for li in uls: book_name = li.find('a').text link = li.find('a')['href'] id_list = list(filter(str.isdigit,link)) book_id = ''.join(id_list) books[book_id] = book_name print(books) 三、帶cookies和參數(shù)請(qǐng)求催更鏈接 將上述兩組代碼組合。 拿到cookies和參數(shù),完成催更請(qǐng)求(不要超過(guò)5次) 我?guī)湍泐A(yù)置了前兩個(gè)代碼,你可以在此基礎(chǔ)上完成本關(guān)卡任務(wù)。 注意: 1. 請(qǐng)求url需要拼接書(shū)籍id 2. 請(qǐng)求時(shí)候別忘了添加請(qǐng)求頭和cookies:cookies=session.cookies 【代碼題】 【預(yù)設(shè)代碼】 選擇語(yǔ)言 # 將上述兩組代碼組合。拿到cookies和參數(shù),完成催更請(qǐng)求。 # 我?guī)湍泐A(yù)置了前兩個(gè)代碼,你可以在此基礎(chǔ)上完成本關(guān)卡任務(wù)。
# 小說(shuō)樓:https://www./ # 小說(shuō)樓登錄:https://www./login.php # 小說(shuō)樓的排行榜:https://www./top/allvisit_1/ # 小說(shuō)樓催更:https://www./modules/article/usercui.php?id= import requests from bs4 import BeautifulSoup
login_url = 'https://www./login.php' hot_url = 'https://www./top/allvisit_1/' urge_url = 'https://www./modules/article/usercui.php?id=' session = requests.session() headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' }
def login_cookies(): data = {'username':input('請(qǐng)輸入你的賬號(hào):'), 'password':input('請(qǐng)輸入你的密碼:'), 'action':'login'} result = session.post(login_url, headers=headers, data=data)
def get_bookids(): result = requests.get(hot_url, headers=headers) result.encoding = 'gbk' bs = BeautifulSoup(result.text,'html.parser') uls = bs.find_all('span',class_='up2') books = {} for li in uls: book_name = li.find('a').text link = li.find('a')['href'] id_list = list(filter(str.isdigit,link)) book_id = ''.join(id_list) books[book_id] = book_name return books
def urge(book_id): # 請(qǐng)求催更鏈接需要拼接book_id # 請(qǐng)求需要帶上headers和cookies
def main (): login_cookies() books = get_bookids() print('--------熱門書(shū)籍--------') for k,v in books.items(): print(k,':',v) book_id = input('請(qǐng)輸入想要催更的書(shū)籍id:') urge(book_id) main() 【解答】 選擇語(yǔ)言 import requests from bs4 import BeautifulSoup
login_url = 'https://www./login.php' hot_url = 'https://www./top/allvisit_1/' urge_url = 'https://www./modules/article/usercui.php?id=' session = requests.session() headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' }
def login_cookies(): data = {'username':input('請(qǐng)輸入你的賬號(hào):'), 'password':input('請(qǐng)輸入你的密碼:'), 'action':'login'} result = session.post(login_url, headers=headers, data=data)
def get_bookids(): result = requests.get(hot_url, headers=headers) result.encoding = 'gbk' bs = BeautifulSoup(result.text,'html.parser') uls = bs.find_all('span',class_='up2') books = {} for li in uls: book_name = li.find('a').text link = li.find('a')['href'] id_list = list(filter(str.isdigit,link)) book_id = ''.join(id_list) books[book_id] = book_name return books
def urge(book_id):
url = urge_url+book_id result = session.get(url, headers=headers, cookies=session.cookies) result.encoding = 'gbk' if result.status_code == 200: bs = BeautifulSoup(result.text,'html.parser') urge_info = bs.find('div',class_='blocktitle').get_text() urge_info2 = bs.find('div',class_='blockcontent').get_text() print(urge_info) print(urge_info2)
def main (): login_cookies() books = get_bookids() print('--------熱門書(shū)籍--------') for k,v in books.items(): print(k,':',v) book_id = input('請(qǐng)輸入想要催更的書(shū)籍id:') urge(book_id) main() 參考答案和總結(jié) 【講解】 參考答案: 選擇語(yǔ)言 # 小說(shuō)樓:https://www./ # 小說(shuō)樓登錄:https://www./login.php # 小說(shuō)樓的排行榜:https://www./top/allvisit_1/ # 小說(shuō)樓催更:https://www./modules/article/usercui.php?id=
import requests from bs4 import BeautifulSoup
login_url = 'https://www./login.php' hot_url = 'https://www./top/allvisit_1/' urge_url = 'https://www./modules/article/usercui.php?id=' session = requests.session() headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' }
def login_cookies(): data = {'username':input('請(qǐng)輸入你的賬號(hào):'), 'password':input('請(qǐng)輸入你的密碼:'), 'action':'login'} result = session.post(login_url, headers=headers, data=data)
def get_bookids(): result = requests.get(hot_url, headers=headers) result.encoding = 'gbk' bs = BeautifulSoup(result.text,'html.parser') uls = bs.find_all('span',class_='up2') books = {} for li in uls: book_name = li.find('a').text link = li.find('a')['href'] id_list = list(filter(str.isdigit,link)) book_id = ''.join(id_list) books[book_id] = book_name return books
def urge(book_id): url = urge_url+book_id result = session.get(url, headers=headers, cookies=session.cookies) result.encoding = 'gbk' if result.status_code == 200: bs = BeautifulSoup(result.text,'html.parser') urge_info = bs.find('div',class_='blocktitle').get_text() urge_info2 = bs.find('div',class_='blockcontent').get_text() print(urge_info) print(urge_info2)
def main (): login_cookies() books = get_bookids() print('--------熱門書(shū)籍--------') for k,v in books.items(): print(k,':',v) book_id = input('請(qǐng)輸入想要催更的書(shū)籍id:') urge(book_id) main() 練習(xí)-自制翻譯器-參考 第一步:分析問(wèn)題,明確目標(biāo) 實(shí)現(xiàn)功能:用戶輸入英文或中文,程序即可打印出來(lái)對(duì)應(yīng)的譯文。 【講解】 我們?cè)谧筮呡斎胛淖?,那么瀏覽器會(huì)把輸入的信息傳輸給服務(wù)器,再返回對(duì)應(yīng)的內(nèi)容。 我們希望達(dá)成的效果如下圖,即用戶輸入英文或中文,程序即可打印出來(lái)對(duì)應(yīng)的譯文: 第二步:思考要用到的知識(shí) 【講解】 實(shí)現(xiàn)一鍵翻譯的功能,最簡(jiǎn)單的方案便是爬蟲(chóng)。在此,我們選擇的網(wǎng)站是有道翻譯。 你在左邊輸入文字,那么瀏覽器會(huì)把你輸入的信息傳輸給服務(wù)器。再返回對(duì)應(yīng)的內(nèi)容。 ?? ?? 這就是一個(gè)典型的Post操作。 我們?cè)贖eaders也可以看到“Request Method: POST”哦~ ?? 在前幾關(guān)練習(xí)我們用的都是Get方式請(qǐng)求,Post是另一種常見(jiàn)的方式,課上已經(jīng)學(xué)過(guò)其用法,在此不多贅述。 __Get是向服務(wù)器發(fā)索取數(shù)據(jù)的一種請(qǐng)求,而Post是向服務(wù)器提交數(shù)據(jù)的一種請(qǐng)求__ 雖然第八關(guān)我們主要講的是Cookies~ __Cookies用于服務(wù)器實(shí)現(xiàn)會(huì)話,用戶登錄及相關(guān)功能時(shí)進(jìn)行狀態(tài)管理__ 但這道題并不需要用到小餅干,因?yàn)椴恍枰卿洸恍枰~號(hào)密碼等。 主要考查的還是Post的用法。 __注意哦__ ?(????) 有道翻譯有反爬蟲(chóng)機(jī)制,它使用了加密技術(shù)。如果你的程序報(bào)錯(cuò),你可以通過(guò)搜索、查閱資料找到解決方案:嘗試把訪問(wèn)的網(wǎng)址中“/translate_o”中的“_o”刪除。 服務(wù)器返回的內(nèi)容,是json的格式。我們可以用處理列表、處理字典的手段來(lái)提取翻譯。 第三步:寫(xiě)代碼 你可以在瀏覽器的[network]-[Headers]-[General]里找到需要訪問(wèn)的網(wǎng)址,在[network]-[Headers]-[From data]里找到需要上傳的數(shù)據(jù)。 __再次注意哦__ ?(????) 有道翻譯有反爬蟲(chóng)機(jī)制,它使用了加密技術(shù)。如果你的程序報(bào)錯(cuò),你可以通過(guò)搜索、查閱資料找到解決方案:嘗試把訪問(wèn)的網(wǎng)址中“/translate_o”中的“_o”刪除。 服務(wù)器返回的內(nèi)容,是json的格式。我們可以用處理列表、處理字典的手段來(lái)提取翻譯。 【解答】 選擇語(yǔ)言 import requests,json #調(diào)用了兩個(gè)模塊。requests負(fù)責(zé)上傳和下載數(shù)據(jù),json負(fù)責(zé)解析。
word = input('你想翻譯什么呀?') url='http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule' #使用post需要一個(gè)鏈接。 data={'i': word, 'from': 'AUTO', 'to': 'AUTO', 'smartresult': 'dict', 'client': 'fanyideskweb', 'doctype': 'json', 'version': '2.1', 'keyfrom': 'fanyi.web', 'action': 'FY_BY_REALTIME', 'typoResult': 'false'} #將需要post的內(nèi)容,以字典的形式記錄在data內(nèi)。 r = requests.post(url,data) #post需要輸入兩個(gè)參數(shù),一個(gè)是剛才的鏈接,一個(gè)是data,返回的是一個(gè)Response對(duì)象。 answer=json.loads(r.text) #你可以自己嘗試print一下r.text的內(nèi)容,然后再閱讀下面的代碼。 print ('翻譯的結(jié)果是:'+answer['translateResult'][0][0]['tgt']) 第四步:套層殼(小彩蛋,了解即可,感興趣的話可以深入學(xué)習(xí)) 我們總會(huì)聽(tīng)到前端后端全棧,感覺(jué)神秘有高大上,你一定很好奇它們都是什么呀? 今天呢,我們就簡(jiǎn)單接觸下前端~ 有米有很期待呀(?>???<‵)?? 前端,是一種GUI軟件。而我們現(xiàn)在要用的是Python里的一個(gè)模塊實(shí)現(xiàn)本地窗口的功能。 它就是Tkinter~ Tkinter 模塊是 Python 的標(biāo)準(zhǔn) Tk GUI 工具包的接口。 Tk 和 Tkinter 可以在大多數(shù)的 Unix 平臺(tái)下使用,同樣可以應(yīng)用在 Windows 和 MacOS系統(tǒng)里。 Tk8.0 的后續(xù)版本可以實(shí)現(xiàn)本地窗口風(fēng)格,并良好地運(yùn)行在絕大多數(shù)平臺(tái)中。 http://www.runoob.com/python/python-gui-tkinter.html 最后的代碼大約是這個(gè)模樣,注意閱讀注釋~ 當(dāng)然你可以在終端運(yùn)行(復(fù)制)這些代碼,觀察效果~ 【解答】 認(rèn)真閱讀注釋,你也可以復(fù)制下來(lái)在你的IDE中運(yùn)行下哦~ 選擇語(yǔ)言 import requests import json from tkinter import Tk,Button,Entry,Label,Text,END
class YouDaoFanyi(object): def __init__(self): pass def crawl(self,word): url='http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule' #使用post需要一個(gè)鏈接 data={'i': word, 'from': 'AUTO', 'to': 'AUTO', 'smartresult': 'dict', 'client': 'fanyideskweb', 'doctype': 'json', 'version': '2.1', 'keyfrom': 'fanyi.web', 'action': 'FY_BY_REALTIME', 'typoResult': 'false'} #將需要post的內(nèi)容,以字典的形式記錄在data內(nèi)。 r = requests.post(url, data) #post需要輸入兩個(gè)參數(shù),一個(gè)是剛才的鏈接,一個(gè)是data,返回的是一個(gè)Response對(duì)象 answer=json.loads(r.text) #你可以自己嘗試print一下r.text的內(nèi)容,然后再閱讀下面的代碼。 result = answer['translateResult'][0][0]['tgt'] return result
class Application(object): def __init__(self): self.window = Tk() self.fanyi = YouDaoFanyi() self.window.title(u'我的翻譯') #設(shè)置窗口大小和位置 self.window.geometry('310x370+500+300') self.window.minsize(310,370) self.window.maxsize(310,370) #創(chuàng)建一個(gè)文本框 #self.entry = Entry(self.window) #self.entry.place(x=10,y=10,width=200,height=25) #self.entry.bind('<Key-Return>',self.submit1) self.result_text1 = Text(self.window,background = 'azure') # 喜歡什么背景色就在這里面找哦,但是有色差,得多試試:http://www.science./dftwiki/index.php/Color_Charts_for_TKinter self.result_text1.place(x = 10,y = 5,width = 285,height = 155) self.result_text1.bind('<Key-Return>',self.submit1) #創(chuàng)建一個(gè)按鈕 #為按鈕添加事件 self.submit_btn = Button(self.window,text=u'翻譯',command=self.submit) self.submit_btn.place(x=205,y=165,width=35,height=25) self.submit_btn2 = Button(self.window,text=u'清空',command = self.clean) self.submit_btn2.place(x=250,y=165,width=35,height=25) #翻譯結(jié)果標(biāo)題 self.title_label = Label(self.window,text=u'翻譯結(jié)果:') self.title_label.place(x=10,y=165) #翻譯結(jié)果 self.result_text = Text(self.window,background = 'light cyan') self.result_text.place(x = 10,y = 190,width = 285,height = 165) #回車翻譯 def submit1(self,event): #從輸入框獲取用戶輸入的值 content = self.result_text1.get(0.0,END).strip().replace('\n',' ') #把這個(gè)值傳送給服務(wù)器進(jìn)行翻譯 result = self.fanyi.crawl(content) #將結(jié)果顯示在窗口中的文本框中 self.result_text.delete(0.0,END) self.result_text.insert(END,result) #print(content)
def submit(self): #從輸入框獲取用戶輸入的值 content = self.result_text1.get(0.0,END).strip().replace('\n',' ') #把這個(gè)值傳送給服務(wù)器進(jìn)行翻譯 result = self.fanyi.crawl(content) #將結(jié)果顯示在窗口中的文本框中 self.result_text.delete(0.0,END) self.result_text.insert(END,result) print(content)
#清空文本域中的內(nèi)容 def clean(self): self.result_text1.delete(0.0,END) self.result_text.delete(0.0,END)
def run(self): self.window.mainloop()
if __name__=='__main__': app = Application() app.run() 練習(xí)-圖靈機(jī)器人-參考 第一步:登錄注冊(cè)圖靈機(jī)器人 注冊(cè)登錄,才能創(chuàng)建自己的圖靈機(jī)器人。 根據(jù)幫助中心的“說(shuō)明書(shū)”,我們可以了解如何運(yùn)用這個(gè)新工具~ 【講解】 進(jìn)入圖靈機(jī)器人官網(wǎng)[http://www./](http://www./),戳進(jìn)幫助中心。 ?? 就像打開(kāi)玩具先看說(shuō)明書(shū)一樣,我們來(lái)看看官方文檔怎么說(shuō)怎么用~ ?? 在功能說(shuō)明中,我們知道,首先得登錄注冊(cè),用免費(fèi)版本就可以了(當(dāng)然~土豪請(qǐng)隨意),創(chuàng)建機(jī)器人在“機(jī)器人設(shè)置”中,我們用的是第一個(gè)API接入 ?? 那什么是API呢?通俗地講: __API就是接口__,就是通道,負(fù)責(zé)一個(gè)程序和其他軟件的溝通,本質(zhì)是預(yù)先定義的函數(shù),而我們不需要了解這個(gè)函數(shù)只是調(diào)用這個(gè)接口就可達(dá)到函數(shù)的效果。 好,接下來(lái)我們看下“API V2.0接入文檔”. ?? 接口說(shuō)明:API接口可調(diào)用聊天對(duì)話、語(yǔ)料庫(kù)、技能三大模塊的語(yǔ)料。 很好,我們今天想做的聊天機(jī)器人用這個(gè)接口就剛巧合適~ 同時(shí),在使用說(shuō)明中我們可以知曉: 首先創(chuàng)建post請(qǐng)求所需的json數(shù)據(jù),然后向指定的接口發(fā)起post請(qǐng)求即可,而且從參數(shù)說(shuō)明中可以看到,只有參數(shù) perception 和 userinfo 才是必須的。 對(duì)于userid這個(gè)參數(shù)官方文檔說(shuō)的是:長(zhǎng)度小于32,是用戶的唯一標(biāo)識(shí),這里我們只要?jiǎng)?chuàng)建userid 是長(zhǎng)度小于32的字符串即可,說(shuō)明書(shū)已經(jīng)看完啦,來(lái),開(kāi)始著手做準(zhǔn)備工作! ?? 那我們回到主頁(yè),注冊(cè)登錄 ?? 然后在機(jī)器人管理界面,創(chuàng)建圖靈機(jī)器人,最多可以創(chuàng)建5個(gè),由此得出對(duì)應(yīng)的5個(gè)apikey。(實(shí)際上一個(gè)就夠啦) apikey是針對(duì)接口訪問(wèn)的授權(quán)方式。 ?? 準(zhǔn)備工作做完啦,接下來(lái)想想該如何寫(xiě)代碼 第二步:創(chuàng)建自己的聊天機(jī)器人 請(qǐng)求過(guò)程:首先創(chuàng)建post請(qǐng)求所需的json數(shù)據(jù),然后向指定的接口發(fā)起post請(qǐng)求即可, 而且從參數(shù)說(shuō)明中可以看到,只有參數(shù) perception 和 userinfo 才是必須的 想不清楚的可以看提示哦~ 【提示】 userid = str(1) 1 可以替換成任何長(zhǎng)度小于32的字符串哦 ~ apikey = str(‘A') 這里的A,記得替換成你自己的apikey哦~ 對(duì)咯,還有件小事需要注意一下,有時(shí)候可能你的代碼沒(méi)有錯(cuò),但最后顯示加密錯(cuò)誤,那是apikey過(guò)期了,不過(guò)沒(méi)關(guān)系,不是可以最多創(chuàng)建5個(gè)機(jī)器人嘛,換一個(gè)apikey試試就好咯~ 【解答】 選擇語(yǔ)言 import requests import json
userid = str(1) # 1 可以替換成任何長(zhǎng)度小于32的字符串哦 apikey = str(''A) # 這里的A,記得替換成你自己的apikey哦~ # 創(chuàng)建post函數(shù) def robot(content): # 圖靈api api = r'http://openapi./openapi/api/v2' # 創(chuàng)建post提交的數(shù)據(jù) data = { 'perception': { 'inputText': { 'text': content } }, 'userInfo': { 'apiKey': apikey, 'userId': userid, } } # 轉(zhuǎn)化為json格式 jsondata = json.dumps(data) # 發(fā)起post請(qǐng)求 response = requests.post(api, data = jsondata) # 將返回的json數(shù)據(jù)解碼 robot_res = json.loads(response.content) # 提取對(duì)話數(shù)據(jù) print(robot_res['results'][0]['values']['text'])
for x in range(10): content = input('talk:') # 輸入對(duì)話內(nèi)容 robot(content) if x == 10: break # 十次之后就結(jié)束對(duì)話,數(shù)字可以改哦,你想幾次就幾次 #當(dāng)然咯,你也可以加一些stopwords,只要說(shuō)了這些詞就可以終止聊天
while True: content = input('talk:') # 輸入對(duì)話內(nèi)容 robot(content) if content == 'bye': # 設(shè)置stopwords break
#但是,我覺(jué)得吧,喜歡和聊天機(jī)器人玩的都是話癆,所以,可以最后加個(gè)死循環(huán),如下:
# 創(chuàng)建對(duì)話死循環(huán) while True: # 輸入對(duì)話內(nèi)容 content = input('talk:') robot(content) 這個(gè)練習(xí)可能會(huì)遇到的問(wèn)題 1、api = r'http://openapi./openapi/api/v2' 為什么要寫(xiě)成這種格式,而不是常規(guī)的網(wǎng)頁(yè)?為啥有個(gè)r? 加r表示絕對(duì)字符串,這樣里面的\就不會(huì)表達(dá)出其他的意思。r是保持字符串原始值的意思,就是說(shuō)不對(duì)其中的符號(hào)進(jìn)行轉(zhuǎn)義。因?yàn)閣indows下的目錄字符串中通常有斜杠'\',而斜杠在Python的字符串中有轉(zhuǎn)義的作用。例如:\n表示換行如果路徑中有\(zhòng)new就會(huì)被轉(zhuǎn)義。加上r就是為了避免這種情況~ 2、對(duì)話限制問(wèn)題 目前圖靈機(jī)器人免費(fèi)用戶對(duì)話限制由原先的100次限制剩3次! 練習(xí)-nlpir人工智能-參考 目前網(wǎng)站無(wú)法訪問(wèn),這個(gè)練習(xí)不用做了哈~ 第9關(guān) 練習(xí)-博客達(dá)人-參考 你需要做的事情是: 首先,登錄博客[人人都是蜘蛛俠](https://wordpress-edu-3autumn.localprod./wp-login.php)。 然后,在文章《未來(lái)已來(lái)(三)——同九義何汝秀》中,發(fā)表一個(gè)評(píng)論,這個(gè)評(píng)論中必須要帶有“selenium”這個(gè)詞。 博客登錄頁(yè)面:https://wordpress-edu-3autumn.localprod./wp-login.php 答這道題的時(shí)候,使用可視模式會(huì)對(duì)運(yùn)行結(jié)果有更直觀的了解,如果你想看到瀏覽器的操作過(guò)程,建議你在本地寫(xiě)好練習(xí)答案,然后再?gòu)?fù)制到這里。 【提示】 使用`selenium`操作瀏覽器的方法,就和人一步一步操作的步驟是一樣的: 1. 獲取網(wǎng)頁(yè) 2. 輸入用戶名與密碼,點(diǎn)擊登錄 3. 點(diǎn)擊《未來(lái)已來(lái)(三)——同九義何汝秀》文章標(biāo)題,進(jìn)入文章頁(yè)面 4. 找到評(píng)論區(qū),輸入評(píng)論,點(diǎn)擊發(fā)表評(píng)論 用到的知識(shí)點(diǎn)都是`selenium`提取數(shù)據(jù)的方法,以及操作元素的方法。 【解答】 特別提示: 從博客首頁(yè)進(jìn)入文章頁(yè)面時(shí),需要用到 find_element_by_partial_link_text 通過(guò)鏈接的部分文本獲取超鏈接。 發(fā)表評(píng)論之后,不會(huì)再終端返回運(yùn)行結(jié)果,記得去博客文章的頁(yè)面去看看自己的評(píng)論有沒(méi)有成功~ 由于教學(xué)系統(tǒng)中與你本地的瀏覽器設(shè)置方法不同,我給你提供了兩份答案,一份可以在課程系統(tǒng)中運(yùn)行,一份可以在你的本地運(yùn)行。 選擇語(yǔ)言 import time from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.webdriver import RemoteWebDriver
# 獲取用戶輸入的評(píng)論內(nèi)容 while True: comment_content = input('請(qǐng)輸入你想要的評(píng)論的內(nèi)容,按回車提交:') if comment_content == '': print('&' * 5, '評(píng)論內(nèi)容不允許為空', '&' * 5) else: break
'''方法一:使用自己電腦上的瀏覽器''' driver = webdriver.Chrome() # 實(shí)例化瀏覽器對(duì)象 driver.get('https://wordpress-edu-3autumn.localprod./wp-login.php') # 訪問(wèn)頁(yè)面 time.sleep(2)
'''方法二:使用教學(xué)系統(tǒng)的瀏覽器設(shè)置,只能在網(wǎng)頁(yè)的在線編輯器上運(yùn)行''' # chrome_options = Options() # 實(shí)例化Option對(duì)象 # chrome_options.add_argument('--headless') # 對(duì)瀏覽器的設(shè)置 # driver = webdriver.Chrome('http://thon-class-fos.svc:4444/wd/hub', # chrome_options.to_capabilities()) # 聲明瀏覽器對(duì)象 # driver.get('https://wordpress-edu-3autumn.localprod./wp-login.php') # 訪問(wèn)頁(yè)面
# 定位到用戶名輸入框,輸入用戶名 login_name = driver.find_element_by_id('user_login') login_name.send_keys('spiderman') time.sleep(1) # 定位到密碼輸入框,輸入密碼 password = driver.find_element_by_id('user_pass') password.send_keys('crawler334566') # 定位到登錄按鈕,并點(diǎn)擊按鈕 submit_btn = driver.find_element_by_id('wp-submit') submit_btn.click() time.sleep(2)
# 通過(guò)鏈接的部分文本定位到'《未來(lái)已來(lái)(三)——同九義何汝秀》'這篇文章 # 獲取到該文章對(duì)應(yīng)的a標(biāo)簽(超鏈接),并點(diǎn)擊鏈接進(jìn)入文章詳情頁(yè) article_link = driver.find_element_by_partial_link_text('同九義何汝秀') article_link.click()
# 進(jìn)入文章詳情頁(yè),定位到該頁(yè)面下編寫(xiě)評(píng)論的文本框,輸入內(nèi)容 comment_area = driver.find_element_by_id('comment') comment_area.send_keys(comment_content) time.sleep(2) # 定位到提交按鈕,點(diǎn)擊該按鈕提交評(píng)論 comment_submit = driver.find_element_by_id('submit') comment_submit.click()
# 評(píng)論成功10秒后關(guān)閉瀏覽器 time.sleep(10) driver.close() print('#' * 6, '評(píng)論成功,瀏覽器已關(guān)閉', '#' * 6) 練習(xí)-Python之禪-參考 題目要求 獲取網(wǎng)站[你好,蜘蛛俠!](https://localprod.m/python-manuscript/hello-spiderman/)的Python之禪中文英對(duì)照文本。 需要通過(guò)兩種方法獲取: - 只使用`selenium` - `selenium`與`BeautifulSoup`配合 【講解】 [你好,蜘蛛俠!](https://localprod.m/python-manuscript/hello-spiderman/)是一個(gè)動(dòng)態(tài)網(wǎng)頁(yè),URL:https://localprod.m/python-manuscript/hello-spiderman/ Python之禪的內(nèi)容沒(méi)有存在網(wǎng)頁(yè)源代碼中,無(wú)法通過(guò)`requests.get()`與`BeautifulSoup`提取“Python之禪”的內(nèi)容,不過(guò),我們可以通過(guò)`selenium`獲取到。 方法如下: 0. 使用`selenium`獲取網(wǎng)頁(yè) 1. 輸入你喜歡的老師和助教,點(diǎn)擊提交 2. 提取`Elements`中渲染完成的完整網(wǎng)頁(yè)源代碼中的,中英文對(duì)照的Python之禪 我在課堂講解中帶你做過(guò)前兩步了,第三步正是你現(xiàn)在需要做的。 我們可以用兩種方式完成它~ 第一種方法: 只使用`selenium`。 第二種方法: 使用`selenium`配合`BeautifulSoup`。 第一種方法:selenium 這次我們要用`selenium`單獨(dú)完成這個(gè)爬蟲(chóng)。獲取數(shù)據(jù)、解析數(shù)據(jù)、提取數(shù)據(jù)這三個(gè)步驟全部都由`selenium`來(lái)完成,寫(xiě)代碼吧~ 【提示】 前面的步驟,在關(guān)卡課程中都已經(jīng)講過(guò),現(xiàn)在要做的是,在它的基礎(chǔ)之上,獲取中英文的“Python之禪”內(nèi)容。 中文和英文版的“Python之禪”都在同樣的標(biāo)簽中。所以,需要先獲取所有的`class_='content'`標(biāo)簽,然后再?gòu)闹蟹謩e提取標(biāo)題與正文。 具體的方法都寫(xiě)在了代碼注釋中。 由于教學(xué)系統(tǒng)中與你本地的瀏覽器設(shè)置方法不同,我給你提供了兩份答案,一份可以在課程系統(tǒng)中運(yùn)行,一份可以在你的本地運(yùn)行。 【解答】 選擇語(yǔ)言 # 下面是只能在爬蟲(chóng)課系統(tǒng)中運(yùn)行的答案: from selenium.webdriver.chrome.webdriver import RemoteWebDriver # 從selenium庫(kù)中調(diào)用RemoteWebDriver模塊 from selenium.webdriver.chrome.options import Options # 從options模塊中調(diào)用Options類 import time
chrome_options = Options() # 實(shí)例化Option對(duì)象 chrome_options.add_argument('--headless') # 把Chrome設(shè)置為靜默模式 driver = RemoteWebDriver('http://thon-class-fos.svc:4444/wd/hub', chrome_options.to_capabilities()) # 設(shè)置瀏覽器引擎為遠(yuǎn)程瀏覽器
chrome_options = Options() # 實(shí)例化Option對(duì)象 chrome_options.add_argument('--headless') # 把Chrome設(shè)置為靜默模式 driver = RemoteWebDriver('http://thon-class-fos.svc:4444/wd/hub', chrome_options.to_capabilities()) # 設(shè)置瀏覽器引擎為遠(yuǎn)程瀏覽器
driver.get('https://localprod.m/python-manuscript/hello-spiderman/') # 訪問(wèn)頁(yè)面 time.sleep(2) # 暫停兩秒,等待瀏覽器緩沖
teacher = driver.find_element_by_id('teacher') # 找到【請(qǐng)輸入你喜歡的老師】下面的輸入框位置 teacher.send_keys('必須是吳楓呀') # 輸入文字 assistant = driver.find_element_by_name('assistant') # 找到【請(qǐng)輸入你喜歡的助教】下面的輸入框位置 assistant.send_keys('都喜歡') # 輸入文字 button = driver.find_element_by_class_name('sub') # 找到【提交】按鈕 button.click() # 點(diǎn)擊【提交】按鈕 time.sleep(1)
contents = driver.find_elements_by_class_name('content') # 定位到Python之禪所在的標(biāo)簽 for content in contents: title = content.find_element_by_tag_name('h1').text # 提取標(biāo)題 chan = content.find_element_by_tag_name('p').text # 提取正文 print(title + '\n' + chan + '\n') # 打印標(biāo)題與正文 driver.close() 選擇語(yǔ)言 # 下面是只能在你的本地運(yùn)行的答案: from selenium import webdriver # 從selenium庫(kù)中調(diào)用webdriver模塊 import time
driver = webdriver.Chrome() # 聲明瀏覽器對(duì)象 driver.get('https://localprod.m/python-manuscript/hello-spiderman/') # 訪問(wèn)頁(yè)面 time.sleep(2) # 暫停兩秒,等待瀏覽器緩沖
teacher = driver.find_element_by_id('teacher') # 找到【請(qǐng)輸入你喜歡的老師】下面的輸入框位置 teacher.send_keys('必須是吳楓呀') # 輸入文字 assistant = driver.find_element_by_name('assistant') # 找到【請(qǐng)輸入你喜歡的助教】下面的輸入框位置 assistant.send_keys('都喜歡') # 輸入文字 button = driver.find_element_by_class_name('sub') # 找到【提交】按鈕 button.click() # 點(diǎn)擊【提交】按鈕 time.sleep(1)
contents = driver.find_elements_by_class_name('content') # 定位到Python之禪所在的標(biāo)簽 for content in contents: title = content.find_element_by_tag_name('h1').text # 提取標(biāo)題 chan = content.find_element_by_tag_name('p').text # 提取正文 print(title + '\n' + chan + '\n') # 打印標(biāo)題與正文 driver.close() 第二種方法:selenium 與 BeautifulSoup配合 先用`selenium`獲取到渲染完成的`Elements`中的網(wǎng)頁(yè)源代碼,然后,`BeautifulSoup`登場(chǎng)解析和提取數(shù)據(jù)。 【提示】 爬取到的文字中,前面會(huì)有一些空格,可以使用`replace(' ','')`去掉文字前面的空格。 這是字符串對(duì)象的一個(gè)方法,它的意思是,把第一個(gè)參數(shù)的字符串用第二個(gè)參數(shù)的字符串替代。 【解答】 具體的方法都寫(xiě)在了代碼注釋中。 由于教學(xué)系統(tǒng)中與你本地的瀏覽器設(shè)置方法不同,我給你提供了兩份答案,一份可以在課程系統(tǒng)中運(yùn)行,一份可以在你的本地運(yùn)行。 選擇語(yǔ)言 # 下面是只能在爬蟲(chóng)課系統(tǒng)中運(yùn)行的答案: from selenium.webdriver.chrome.webdriver import RemoteWebDriver # 從selenium庫(kù)中調(diào)用RemoteWebDriver模塊 from selenium.webdriver.chrome.options import Options # 從options模塊中調(diào)用Options類 from bs4 import BeautifulSoup import time
chrome_options = Options() # 實(shí)例化Option對(duì)象 chrome_options.add_argument('--headless') # 把Chrome設(shè)置為靜默模式 driver = RemoteWebDriver('http://thon-class-fos.svc:4444/wd/hub', chrome_options.to_capabilities()) # 設(shè)置瀏覽器引擎為遠(yuǎn)程瀏覽器
driver.get('https://localprod.m/python-manuscript/hello-spiderman/') # 訪問(wèn)頁(yè)面 time.sleep(2) # 暫停兩秒,等待瀏覽器緩沖
teacher = driver.find_element_by_id('teacher') # 定位到【請(qǐng)輸入你喜歡的老師】下面的輸入框位置 teacher.send_keys('必須是吳楓呀') # 輸入文字 assistant = driver.find_element_by_name('assistant') # 定位到【請(qǐng)輸入你喜歡的助教】下面的輸入框位置 assistant.send_keys('都喜歡') # 輸入文字 button = driver.find_element_by_class_name('sub') # 定位到【提交】按鈕 button.click() # 點(diǎn)擊【提交】按鈕 time.sleep(1) # 等待一秒
pageSource = driver.page_source # 獲取頁(yè)面信息 soup = BeautifulSoup(pageSource,'html.parser') # 使用bs解析網(wǎng)頁(yè) contents = soup.find_all(class_='content') # 找到源代碼Python之禪中文版和英文版所在的元素 for content in contents: # 遍歷列表 title = content.find('h1').text # 提取標(biāo)題 chan = content.find('p').text.replace(' ','') # 提取Python之禪的正文,并且去掉文字前面的所有空格 print(title + chan + '\n') # 打印Python之禪的標(biāo)題與正文 driver.close()
# 下面是只能在你的本地運(yùn)行的答案: from selenium import webdriver # 從selenium庫(kù)總調(diào)用webdriver模塊 import time from bs4 import BeautifulSoup
driver = webdriver.Chrome() # 聲明瀏覽器對(duì)象 driver.get('https://localprod.m/python-manuscript/hello-spiderman/') # 訪問(wèn)頁(yè)面 time.sleep(2) # 暫停兩秒,等待瀏覽器緩沖
teacher = driver.find_element_by_id('teacher') # 定位到【請(qǐng)輸入你喜歡的老師】下面的輸入框位置 teacher.send_keys('必須是吳楓呀') # 輸入文字 assistant = driver.find_element_by_name('assistant') # 定位到【請(qǐng)輸入你喜歡的助教】下面的輸入框位置 assistant.send_keys('都喜歡') # 輸入文字 button = driver.find_element_by_class_name('sub') # 定位到【提交】按鈕 button.click() # 點(diǎn)擊【提交】按鈕 time.sleep(1) # 等待一秒
pageSource = driver.page_source # 獲取頁(yè)面信息 soup = BeautifulSoup(pageSource,'html.parser') # 使用bs解析網(wǎng)頁(yè) contents = soup.find_all(class_='content') # 找到源代碼Python之禪中文版和英文版所在的元素 for content in contents: # 遍歷列表 title = content.find('h1').text # 提取標(biāo)題 chan = content.find('p').text.replace(' ','') # 提取Python之禪的正文,并且去掉文字前面的所有空格 print(title + chan + '\n') # 打印Python之禪的標(biāo)題與正文 driver.close() 第10關(guān) 練習(xí)-周末吃什么-參考 第一步:明確目標(biāo) 先明確目標(biāo):我們?cè)诘?關(guān)爬取了下廚房網(wǎng)站中的“本周最受歡迎菜譜”,現(xiàn)在,我們完善這個(gè)程序,讓程序在每個(gè)周五爬取數(shù)據(jù),并把菜譜發(fā)送到我們的郵箱。 【講解】 先明確目標(biāo):我們?cè)诘?關(guān)爬取了下廚房網(wǎng)站中的“本周最受歡迎菜譜”,現(xiàn)在,我們完善這個(gè)程序,讓程序在每個(gè)周五爬取數(shù)據(jù),并把菜譜發(fā)送到我們的郵箱。 該項(xiàng)目和第10關(guān)課堂的項(xiàng)目是非常相似的。 第二步:分析過(guò)程 再分析過(guò)程:這個(gè)程序一共分為三部分:爬蟲(chóng)、通知和定時(shí)。 【講解】 這個(gè)程序一共分為三部分,知識(shí)我們都掌握了。 0.爬蟲(chóng):爬取下廚房網(wǎng)站中本周最歡迎菜譜的菜名、鏈接、原材料。 1.通知:用smtplib、email庫(kù)來(lái)發(fā)送郵件。 2.定時(shí):用schedule和time庫(kù)定時(shí)執(zhí)行程序。 我們分別寫(xiě)出來(lái),然后封裝成函數(shù)。 先把每個(gè)程序?qū)懗鰜?lái),然后拼裝到一起;鑒于爬蟲(chóng)程序已經(jīng)學(xué)過(guò),就直接把代碼提供給大家。 第三步:代碼實(shí)現(xiàn) 接下來(lái)就是寫(xiě)代碼啦。 0.爬蟲(chóng):爬蟲(chóng)代碼已經(jīng)在課堂上學(xué)過(guò),所以直接把爬蟲(chóng)代碼提供給大家,并請(qǐng)大家先封裝爬蟲(chóng)代碼: 選擇語(yǔ)言 import requests from bs4 import BeautifulSoup
res_foods = requests.get('http://www.xiachufang.com/explore/') bs_foods = BeautifulSoup(res_foods.text,'html.parser') list_foods = bs_foods.find_all('div',class_='info pure-u')
list_all = []
for food in list_foods: tag_a = food.find('a') name = tag_a.text[17:-13] URL = 'http://www.xiachufang.com'+tag_a['href'] tag_p = food.find('p',class_='ing ellipsis') ingredients = tag_p.text[1:-1] list_all.append([name,URL,ingredients]) print(list_all) 1.郵件:郵件代碼是第10關(guān)所學(xué)的內(nèi)容,下面提供代碼給大家,但最好是回憶不起來(lái)再看;寫(xiě)完代碼后請(qǐng)大家封裝代碼。 (仍然提醒同學(xué)們,學(xué)習(xí)系統(tǒng)會(huì)記錄大家輸入的內(nèi)容??紤]到信息隱私的問(wèn)題,大家不要在這里輸入自己的郵箱密碼或賬號(hào)。因此,請(qǐng)你在本地運(yùn)行郵件相關(guān)的代碼) 選擇語(yǔ)言 import smtplib from email.mime.text import MIMEText from email.header import Header #引入smtplib、MIMETex和Header
mailhost='smtp.qq.com' #把qq郵箱的服務(wù)器地址賦值到變量mailhost上,地址應(yīng)為字符串格式 qqmail = smtplib.SMTP() #實(shí)例化一個(gè)smtplib模塊里的SMTP類的對(duì)象,這樣就可以調(diào)用SMTP對(duì)象的方法和屬性了 qqmail.connect(mailhost,25) #連接服務(wù)器,第一個(gè)參數(shù)是服務(wù)器地址,第二個(gè)參數(shù)是SMTP端口號(hào)。 #以上,皆為連接服務(wù)器。
account = input('請(qǐng)輸入你的郵箱:') #獲取郵箱賬號(hào),為字符串格式 password = input('請(qǐng)輸入你的密碼:') #獲取郵箱密碼,為字符串格式 qqmail.login(account,password) #登錄郵箱,第一個(gè)參數(shù)為郵箱賬號(hào),第二個(gè)參數(shù)為郵箱密碼 #以上,皆為登錄郵箱。
receiver=input('請(qǐng)輸入收件人的郵箱:') #獲取收件人的郵箱。
content=input('請(qǐng)輸入郵件正文:') #輸入你的郵件正文,為字符串格式 message = MIMEText(content, 'plain', 'utf-8') #實(shí)例化一個(gè)MIMEText郵件對(duì)象,該對(duì)象需要寫(xiě)進(jìn)三個(gè)參數(shù),分別是郵件正文,文本格式和編碼 subject = input('請(qǐng)輸入你的郵件主題:') #輸入你的郵件主題,為字符串格式 message['Subject'] = Header(subject, 'utf-8') #在等號(hào)的右邊是實(shí)例化了一個(gè)Header郵件頭對(duì)象,該對(duì)象需要寫(xiě)入兩個(gè)參數(shù),分別是郵件主題和編碼,然后賦值給等號(hào)左邊的變量message['Subject']。 #以上,為填寫(xiě)主題和正文。
try: qqmail.sendmail(account, receiver, message.as_string()) print ('郵件發(fā)送成功') except: print ('郵件發(fā)送失敗') qqmail.quit() #以上為發(fā)送郵件和退出郵箱 2.定時(shí):定時(shí)功能是第10關(guān)教的內(nèi)容,代碼如下,下面提供代碼給大家,但最好回憶不起來(lái)再看;寫(xiě)完代碼后請(qǐng)大家封裝代碼。 選擇語(yǔ)言 import schedule import time #引入schedule和time def job(): print('I'm working...') #定義一個(gè)叫job的函數(shù),函數(shù)的功能是打印'I'm working...' schedule.every(10).minutes.do(job) #部署每10分鐘執(zhí)行一次job()函數(shù)的任務(wù) schedule.every().hour.do(job) #部署每×小時(shí)執(zhí)行一次job()函數(shù)的任務(wù) schedule.every().day.at('10:30').do(job) #部署在每天的10:30執(zhí)行job()函數(shù)的任務(wù) schedule.every().monday.do(job) #部署每個(gè)星期一執(zhí)行job()函數(shù)的任務(wù) schedule.every().wednesday.at('13:15').do(job)#部署每周三的13:15執(zhí)行函數(shù)的任務(wù) while True: schedule.run_pending() time.sleep(1) 【解答】 老師提供的參考答案是這樣的: 選擇語(yǔ)言 import requests import smtplib import schedule import time from bs4 import BeautifulSoup from email.mime.text import MIMEText from email.header import Header
account = input('請(qǐng)輸入你的郵箱:') password = input('請(qǐng)輸入你的密碼:') receiver = input('請(qǐng)輸入收件人的郵箱:')
def recipe_spider(): headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} res_foods = requests.get('http://www.xiachufang.com/explore/',headers=headers) bs_foods = BeautifulSoup(res_foods.text,'html.parser') list_foods = bs_foods.find_all('div',class_='info pure-u') list_all = '' num=0 for food in list_foods: num=num+1 tag_a = food.find('a') name = tag_a.text.strip() url = 'http://www.xiachufang.com'+tag_a['href'] tag_p = food.find('p',class_='ing ellipsis') ingredients = tag_p.text.strip() food_info = ''' 序號(hào): %s 菜名: %s 鏈接: %s 原料: %s '''%(num,name,url,ingredients) list_all=list_all+food_info return(list_all)
def send_email(list_all): global account,password,receiver mailhost='smtp.qq.com' qqmail = smtplib.SMTP() qqmail.connect(mailhost,25) qqmail.login(account,password) content= '親愛(ài)的,本周的熱門菜譜如下'+list_all message = MIMEText(content, 'plain', 'utf-8') subject = '周末吃個(gè)啥' message['Subject'] = Header(subject, 'utf-8') try: qqmail.sendmail(account, receiver, message.as_string()) print ('郵件發(fā)送成功') except: print ('郵件發(fā)送失敗') qqmail.quit()
def job(): print('開(kāi)始一次任務(wù)') list_all = recipe_spider() send_email(list_all) print('任務(wù)完成')
schedule.every().friday.at('18:00').do(job)#部署每周三的13:15執(zhí)行函數(shù)的任務(wù) while True: schedule.run_pending() time.sleep(1) 練習(xí)-看個(gè)電影吧-參考 第一步:明確目標(biāo) 先明確目標(biāo):每個(gè)周五,程序在豆瓣TOP250榜單中隨機(jī)選取三部電影,然后去爬取三部電影的下載鏈接,并把鏈接發(fā)送到我們的郵箱。 【講解】 先明確目標(biāo):每個(gè)周五,程序在豆瓣TOP250榜單中隨機(jī)選取三部電影,然后去爬取三部電影的下載鏈接,并把鏈接發(fā)送到我們的郵箱。該項(xiàng)目和第10關(guān)課堂的是非常相似的。 第二步:分析過(guò)程 我們來(lái)看看這個(gè)項(xiàng)目的實(shí)現(xiàn)思路。 【講解】 這個(gè)程序一共分為四部分: ?? 0.電影榜單爬蟲(chóng):爬取豆瓣電影Top250的榜單,并存儲(chǔ)文件到本地。 1.電影鏈接爬蟲(chóng):每周五讀取榜單中的三部電影,然后去爬取電影的下載鏈接。 2.通知功能:再把爬到的鏈接以郵件的形式發(fā)送給自己。 3.定時(shí)功能:用schedule和time庫(kù)定時(shí)執(zhí)行程序。 可以把4段代碼分別寫(xiě)出來(lái),然后封裝成函數(shù)。鑒于爬蟲(chóng)程序已經(jīng)做過(guò)練習(xí),會(huì)直接把代碼提供給大家。 電影榜單的爬蟲(chóng)是第3關(guān)課后的必做練習(xí),電影鏈接的爬蟲(chóng)是第3關(guān)的選做練習(xí),所以該練習(xí)的重點(diǎn)不會(huì)放在爬蟲(chóng)上。 第三步:代碼實(shí)現(xiàn)(上) 【代碼實(shí)現(xiàn)】又分為上中下。上、中分別把四段代碼寫(xiě)出來(lái),下是封裝組裝代碼。 上:每周五晚上去豆瓣電影Top250的榜單上隨機(jī)抽取3部,然后去下載這3部電影的鏈接,并打印出來(lái)。 先把兩段爬蟲(chóng)的代碼提供給大家,請(qǐng)大家先閱讀,然后去寫(xiě)代碼。(當(dāng)然,你用你自己寫(xiě)的代碼也是一樣的,只要最后實(shí)現(xiàn)的功能和題目一致) 選擇語(yǔ)言 #這是爬取豆瓣電影Top250,并存為本地csv的代碼 import requests, random, csv from bs4 import BeautifulSoup csv_file=open('movieTop.csv', 'w', newline='',encoding='utf-8') writer = csv.writer(csv_file)
for x in range(10): headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} url = 'https://movie.douban.com/top250?start=' + str(x*25) + '&filter=' res = requests.get(url,headers=headers) bs = BeautifulSoup(res.text, 'html.parser') bs = bs.find('ol', class_='grid_view') for titles in bs.find_all('li'): title = titles.find('span', class_='title').text list1 = [title] writer.writerow(list1) csv_file.close()
選擇語(yǔ)言 # 這是爬電影的下載鏈接的代碼 import requests from bs4 import BeautifulSoup from urllib.request import quote
movie=input('你想看什么電影?') gbkmovie = movie.encode('gbk') headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} urlsearch = 'http://s./plus/so.php?typeid=1&keyword='+quote(gbkmovie) res = requests.get(urlsearch,headers=headers) res.encoding='gbk' soup_movie = BeautifulSoup(res.text,'html.parser') urlpart=soup_movie.find(class_='co_content8').find_all('table') if urlpart: urlpart=urlpart[0].find('a')['href'] urlmovie='https://www./'+urlpart res1=requests.get(urlmovie) res1.encoding='gbk' soup_movie1=BeautifulSoup(res1.text,'html.parser') urldownload=soup_movie1.find('div',id='Zoom').find('span').find('table').find('a')['href'] print(urldownload) else: print('沒(méi)有'+movie+'的鏈接') 好,現(xiàn)在,我們需要先讀取存儲(chǔ)到本地的電影榜單的csv文件,然后用random庫(kù)來(lái)隨機(jī)抽取三部電影,再去下載相應(yīng)的電影鏈接,并把電影鏈接打印出來(lái)。 請(qǐng)開(kāi)始寫(xiě)代碼吧。 【提示】 如果對(duì)這里的爬蟲(chóng)代碼有疑惑,建議先完成第3關(guān)的練習(xí)和第6關(guān)的練習(xí)。 【解答】 選擇語(yǔ)言 import requests,csv,random from bs4 import BeautifulSoup from urllib.request import quote # 以上,為引入相應(yīng)的庫(kù)。
csv_file=open('movieTop.csv', 'w', newline='',encoding='utf-8') writer = csv.writer(csv_file) for x in range(10): headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} url = 'https://movie.douban.com/top250?start=' + str(x*25) + '&filter=' res = requests.get(url,headers=headers) bs = BeautifulSoup(res.text, 'html.parser') bs = bs.find('ol', class_='grid_view') for titles in bs.find_all('li'): title = titles.find('span', class_='title').text list1 = [title] writer.writerow(list1) csv_file.close() # 以上,為爬取豆瓣電影Top250的榜單,并存儲(chǔ)為本地的csv文件。
movielist=[] csv_file=open('movieTop.csv','r',newline='',encoding='utf-8') reader=csv.reader(csv_file) for row in reader: movielist.append(row[0]) # 以上,為讀取豆瓣電影Top250榜單的csv文件,并寫(xiě)入列表movielist中。 three_movies=random.sample(movielist,3) # 以上,是從列表movielist中,隨機(jī)抽取三部電影,取出來(lái)的是一個(gè)列表。 for movie in three_movies: # 以上,是把電影名從列表中取出來(lái),并把其數(shù)據(jù)類型變?yōu)樽址O旅骈_(kāi)始,就是你熟悉的下載電影鏈接的代碼了。 gbkmovie = movie.encode('gbk') headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} urlsearch = 'http://s./plus/so.php?typeid=1&keyword='+quote(gbkmovie) res = requests.get(urlsearch,herders=headers) res.encoding='gbk' soup_movie = BeautifulSoup(res.text,'html.parser') urlpart=soup_movie.find(class_='co_content8').find_all('table') if urlpart: urlpart=urlpart[0].find('a')['href'] urlmovie='https://www./'+urlpart res1=requests.get(urlmovie) res1.encoding='gbk' soup_movie1=BeautifulSoup(res1.text,'html.parser') urldownload=soup_movie1.find('div',id='Zoom').find('span').find('table').find('a')['href'] content=movie+'\n'+urldownload print(content) else: content='沒(méi)有'+movie+'的下載鏈接' print(content) 第四步:代碼實(shí)現(xiàn)(中) 接下來(lái),我們來(lái)完成發(fā)送郵件,以及定時(shí)功能的代碼,然后在下一步我們?cè)俜庋b、組合四段代碼。 郵件代碼是第10關(guān)所學(xué)的內(nèi)容,下面提供代碼給大家。 (仍然提醒同學(xué)們,學(xué)習(xí)系統(tǒng)會(huì)記錄大家輸入的內(nèi)容??紤]到信息隱私的問(wèn)題,大家不要在這里輸入自己的郵箱密碼或賬號(hào)。因此,請(qǐng)你在本地運(yùn)行郵件相關(guān)的代碼) 選擇語(yǔ)言 import smtplib from email.mime.text import MIMEText from email.header import Header #引入smtplib、MIMETex和Header
mailhost='smtp.qq.com' #把qq郵箱的服務(wù)器地址賦值到變量mailhost上,地址應(yīng)為字符串格式 qqmail = smtplib.SMTP() #實(shí)例化一個(gè)smtplib模塊里的SMTP類的對(duì)象,這樣就可以調(diào)用SMTP對(duì)象的方法和屬性了 qqmail.connect(mailhost,25) #連接服務(wù)器,第一個(gè)參數(shù)是服務(wù)器地址,第二個(gè)參數(shù)是SMTP端口號(hào)。 #以上,皆為連接服務(wù)器。
account = input('請(qǐng)輸入你的郵箱:') #獲取郵箱賬號(hào),為字符串格式 password = input('請(qǐng)輸入你的密碼:') #獲取郵箱密碼,為字符串格式 qqmail.login(account,password) #登錄郵箱,第一個(gè)參數(shù)為郵箱賬號(hào),第二個(gè)參數(shù)為郵箱密碼 #以上,皆為登錄郵箱。
receiver=input('請(qǐng)輸入收件人的郵箱:') #獲取收件人的郵箱。
#content為上面的電影鏈接 #輸入你的郵件正文,為字符串格式 message = MIMEText(content, 'plain', 'utf-8') #實(shí)例化一個(gè)MIMEText郵件對(duì)象,該對(duì)象需要寫(xiě)進(jìn)三個(gè)參數(shù),分別是郵件正文,文本格式和編碼 subject = '電影鏈接' #輸入你的郵件主題,為字符串格式 message['Subject'] = Header(subject, 'utf-8') #在等號(hào)的右邊是實(shí)例化了一個(gè)Header郵件頭對(duì)象,該對(duì)象需要寫(xiě)入兩個(gè)參數(shù),分別是郵件主題和編碼,然后賦值給等號(hào)左邊的變量message['Subject']。 #以上,為填寫(xiě)主題和正文。
try: qqmail.sendmail(account, receiver, message.as_string()) print ('郵件發(fā)送成功') except: print ('郵件發(fā)送失敗') qqmail.quit() #以上為發(fā)送郵件和退出郵箱
#定時(shí)功能是第10關(guān)教的內(nèi)容,代碼如下,下面提供代碼給大家,但最好回憶不起來(lái)再看。 import schedule import time #引入schedule和time def job(): print('I'm working...') #定義一個(gè)叫job的函數(shù),函數(shù)的功能是打印'I'm working...'
schedule.every(10).minutes.do(job) #部署每10分鐘執(zhí)行一次job()函數(shù)的任務(wù) schedule.every().hour.do(job) #部署每×小時(shí)執(zhí)行一次job()函數(shù)的任務(wù) schedule.every().day.at('10:30').do(job)#部署每天的10:30執(zhí)行job()函數(shù)任務(wù) schedule.every().monday.do(job) #部署每個(gè)星期一執(zhí)行job()函數(shù)的任務(wù) schedule.every().wednesday.at('13:15').do(job) #部署每周三的13:15執(zhí)行函數(shù)的任務(wù)
while True: schedule.run_pending() time.sleep(1) 【解答】 老師提供的參考答案是這樣的: 選擇語(yǔ)言 import requests,csv,random,smtplib,schedule,time from bs4 import BeautifulSoup from urllib.request import quote from email.mime.text import MIMEText from email.header import Header
def get_movielist(): csv_file=open('movieTop.csv', 'w', newline='',encoding='utf-8') writer = csv.writer(csv_file) for x in range(10): headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} url = 'https://movie.douban.com/top250?start=' + str(x*25) + '&filter=' res = requests.get(url,headers=headers) bs = BeautifulSoup(res.text, 'html.parser') bs = bs.find('ol', class_='grid_view') for titles in bs.find_all('li'): title = titles.find('span', class_='title').text list1 = [title] writer.writerow(list1) csv_file.close()
def get_randommovie(): movielist=[] csv_file=open('movieTop.csv','r',newline='',encoding='utf-8') reader=csv.reader(csv_file) for row in reader: movielist.append(row[0]) three_movies=random.sample(movielist,3) contents='' for movie in three_movies: gbkmovie = movie.encode('gbk') headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} urlsearch = 'http://s./plus/so.php?typeid=1&keyword='+quote(gbkmovie) res = requests.get(urlsearch,headers=headers) res.encoding='gbk' soup_movie = BeautifulSoup(res.text,'html.parser') urlpart=soup_movie.find(class_='co_content8').find_all('table') if urlpart: urlpart=urlpart[0].find('a')['href'] urlmovie='https://www./'+urlpart res1=requests.get(urlmovie) res1.encoding='gbk' soup_movie1=BeautifulSoup(res1.text,'html.parser') urldownload=soup_movie1.find('div',id='Zoom').find('span').find('table').find('a')['href'] content=movie+'\n'+urldownload+'\n\n' print(content) contents=contents+content else: content='沒(méi)有'+movie+'的下載鏈接' print(content) return contents
def send_movielink(contents): mailhost='smtp.qq.com' qqmail = smtplib.SMTP() qqmail.connect(mailhost,25) account = '×××××××××@qq.com' # 因?yàn)槭亲约喊l(fā)給自己,所以郵箱賬號(hào)、密碼都可以提前設(shè)置好,當(dāng)然,也可以發(fā)給別人啦 password = '×××××××××××××××' # 因?yàn)槭亲约喊l(fā)給自己,所以郵箱賬號(hào)、密碼都可以提前設(shè)置好,當(dāng)然,也可以發(fā)給別人啦。 qqmail.login(account,password) receiver='×××××××××@qq.com' # 因?yàn)槭亲约喊l(fā)給自己,所以郵箱賬號(hào)、密碼都可以提前設(shè)置好,當(dāng)然,也可以發(fā)給別人啦。 message = MIMEText(contents, 'plain', 'utf-8') subject = '電影鏈接' message['Subject'] = Header(subject, 'utf-8') try: qqmail.sendmail(account, receiver, message.as_string()) print ('郵件發(fā)送成功') except: print ('郵件發(fā)送失敗') qqmail.quit()
def job(): get_movielist() contents=get_randommovie() send_movielink(contents)
schedule.every().friday.at('18:00').do(job) while True: schedule.run_pending() time.sleep(1)
|