整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          VS2019上用C#和ASP.NET寫WebForm網頁的試練

          前言

          NET平臺的VS2019還是挺爽手的IDE,寫WinForm較寫WebForm程序寫起來方便,畢竟項目所需資源基本上都在本地,而WebForm不僅需要IIS支持,還需要其它Script幫助。據說MS出了ASP5,微軟自己用的網絡平臺是基于.NET和ASP5的。MS能跑在.NET和ASP上,其它小網站當然不在話下。其實VS2019上,有MVC模式可參選,但初步印象好像不是Ruby on Rail那樣的MVC實例化了。先搭個WebForm找找感覺,如果能激發出足夠的熱情,后面的事就好開展了。

          2 主要工作

          1. 在Win10上創建IIS服務

          2. 用VS2019 C#試練ASP的WebForm

          2.1 在Win10上創建IIS服務

          在Win10上找到控制面版,打開它,點類別選圖標方式。

          圖標方式列出各分項功能,找到“程序和功能”項。?

          進入程序和功能,找到左上角的“啟用或關閉Windows功能” ?

          在彈出頁面上點選Internet Information Services和Internet Information Services可承載的Web核心項 ?

          點擊確定后,打開本地瀏覽器,輸入localhost,也就是127.0.0.1,IIS默認的首頁就出來了,說明IIS啟用正常。?

          2.2 用VS2019 C#試練ASP的WebForm

          在VS2019上新建項目,選ASP.NET Web 應用程序(.NET Framework)項。由于列示的模板比較多,要耐心點找到它。?

          雙擊它,即進入配置新項目頁。在此頁將位置設置一下,比如 E:\aspnet1 ?

          其它名字和框架之類的就用默認的吧。然后,點擊創建,之后的頁面上選空項目模板,其它的默認。接下來,點擊創建。?

          在資源管理器的項目WebApplication1黑體字上點右鍵,添加,新建項。?

          在新建項出來的頁面上,點選畫著藍色圓皮球的 “Web”窗體。?

          資源管理器內容變成這個樣子 ?

          源,即前臺瀏覽器的代碼;設計,即web界面。WEB界面設計與WinForm類似但不同,虛格里面是放控件的地方,可以點擊伸縮它。其上面可插入HTML標記,SCRIPT標記等(IIS支持的腳本均可用,也可以給IIS安裝擴展其它比如Perl的解釋器等),這些操作可以在“源”里直接編輯的。?

          ?

          3 寫WebForm程序

          在設計頁,點左邊“工具箱”,將Label,Button分別拖到界面上。在“源”頁,加上<H2></H2>標記的一行大字“A simple WebPage of ASP.NET”,再一行普通<p></p>標記的小字“On Microsoft VS2019 IDE, C# is a good partner of ASP.NET for dynamic webpages”,在設計頁面也可以改寫它們的。?

          接下來,是雙擊Button,寫上C#代碼。

          - 點擊Button,改換Label1和Label2的文字

          - 點擊Button, 寫文本文件再讀出記錄顯示在Label上(加上幾行ADO的代碼,可以操作數據庫的)?

          4 運行

          Ctrl+S 保存, Ctrl+B生成,然后運行,Edge瀏覽器顯示如圖。?

          瀏覽器被自動打開,所做的WebForm頁就顯示出來了。如果你的計算機有公網固定IP地址,在遙遠的互聯網上也能看到你的主頁的。

          因為是開發方式,不是正式的部署,它并未使用IIS默認的80端口,遠程訪問時不能只訪問IP地址,要帶上端口號。如果沒有公網固定IP地址,可以申請花生殼免費的賬號,安上它的軟件即可穿透小區網,把你的計算機反向代理到公網,互聯網上即可以訪問你的計算機。這離做個真實像樣的網站還有很多距離,沒做母板也沒有活動頁,數據和頁面傻傻的不能實時變化數據,數據庫沒帶上,但搭了架子可以讓各種Script語言幫助解決。MVC三層模型好是好,看了看VBSCRIP寫的ASP.NET的POPASP的MVC資料,覺得它的最后一版可以快速開發站點用了。哎,亂七八糟的一堆東西,了解一下還好,真要做事還是要辛苦得多。

          ??

          慮到現在大部分小伙伴使用 Python 主要因為爬蟲,那么為了更好地幫助大家鞏固爬蟲知識,加深對爬蟲的理解,選擇了爬取百度文庫作為我們的目標。

          廢話不多說,我們開始。

          TXT、DOCX 爬取與保存

          這是小編準備的python基礎學習資料,關注,轉發,私信小編“01”即可免費領取!

          在爬取任何東西之前,我們都要先確認需要爬取的數據是不是異步加載的;如果是異步加載的直接爬取網頁是爬不到的。

          要知道是不是異步加載其實很簡單,就用requests 對網頁發起請求,看看 response 是什么就可以了

          url = 'https://wenku.baidu.com/view/4e29e5a730126edb6f1aff00bed5b9f3f90f72e7.html?rec_flag=default'
          header = {'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}
          res = requests.get(url , headers = header)
          res.text
          
          

          很明顯,返回的東西,并不是我們所需要的內容; 根據常理來說,我們就可以認為該網頁是異步加載的。

          但是,從常識來講,如果網頁的內容是異步加載的,那么直接通過百度搜索,是搜索不到網頁內部的內容的,但是很顯然,我們每次通過百度搜索都是可以直接找到文庫中的文本內容的。

          如下:

          那么這就有意思了,明明直接發起請求是獲取不到網頁內容的,但是為什么通過百度搜索就可以找到呢? 關鍵肯定在于百度搜索 上面。

          這個時候通過查閱資料,我們了解到,最主要的問題出在我們的 headers

          在爬取網頁時,headers 通常是作為身份證,讓網頁不看出我們是爬蟲;如果不加 headers,網頁直接就會看出我們是爬蟲,就會拒絕訪問

          再深入了解一下 headers 的識別機理,我們發現了叫做 Robot 協議的東西。

          它規定了什么樣的 headers 可以訪問網頁內部內容,除了指定 headers 之外的 headers,都是無法請求頁面內容的。

          比如說百度文庫的 Robot 協議就是下面這樣的:

          User-agent: Baiduspider
          
          Disallow: /w?
          
          Disallow: /search?
          
          Disallow: /submit
          
          Disallow: /upload
          
          Disallow: /cashier/   
          

          而我們需要爬取的內容 url 格式為

          https://wenku.baidu.com/view/?.html

          這代表 Baiduspider 應該可以爬取文庫內容;大致猜測這是因為百度搜索時需要根據文本內容匹配搜索選項,所以放行。

          因此我們嘗試偽裝 UA 為 Baiduspider

          url = 'https://wenku.baidu.com/view/4e29e5a730126edb6f1aff00bed5b9f3f90f72e7.html?rec_flag=default'
          header = {'User-agent': 'Googlebot'}
          res = requests.get(url , headers = header)
          res.text
          

          果然不出所料,我們成功地獲取到了目標內容

          既然已經成功獲取到了網頁的正確源代碼,那么下一步就是去解析網頁獲取內容。

          解析網頁源代碼的庫有很多,這里我們使用 BeautifulSoup

          plist = []
          soup = BeautifulSoup(r, "html.parser")
          plist.append(soup.title.string)
          for div in soup.find_all('div', attrs={"class": "bd doc-reader"}):
              plist.extend(div.get_text().split('\n'))
          plist = [c.replace(' ', '') for c in plist]
          plist = [c.replace('\x0c', '') for c in plist]
          plist
          

          整個解析是非常容易的,都是很標準的操作。

          在這里就不多加敘述了,最終的效果如下:

          當然爬取到東西了只是萬里長征的第一步,就這樣是肯定不行的,我們還需要將爬取的內容保存起來,通常是保存為 txt 文件

          file = open('test.txt', 'w',encoding='utf-8')
          for str in plist:
              file.write(str)
              file.write('\n')
          file.close()
          

          但是為了美觀起見,我們在這里選擇使用 python-docx 庫將內容保存為 docx 文件

          with open('test.txt', encoding='utf-8') as f:
              docu = Document()
              docu.add_paragraph(f.read())
              docu.save('test.docx')
          

          PPT、PDF 爬取與保存

          有了之前的經驗教訓,在爬取的時候我們首先就嘗試了使用爬取 TXT、DOCX 的方法,嘗試是否可以爬到內容

          url = 'https://wenku.baidu.com/view/a4ac1b57dd88d0d232d46a0f.html?fr=search'
          header = {'User-agent': 'Googlebot'}
          res = requests.get(url , headers = header)
          res.text
          

          很可惜的是,我們并沒有訪問到

          原因仔細想想也很簡單,在百度搜索的時候,直接搜索是搜不到 PPT 或者 PDF 的內容的

          那么很顯然,PPT 和 PDF 是通過異步的方法進行內容加載的

          對待異步加載的數據,我們通常采取的策略有兩種

          1、第一個就是直接找到發起異步請求的接口,自己構造請求頭,發起請求

          2、第二個就是通過 Selenium 這樣的自動化測試工具去爬取

          百度文庫的接口太難找了,請求頭的構造也很麻煩,找了很久也沒有很滿意。

          所以在本次爬取中,我們使用的是第二種方法,使用 Selenium 這樣的自動化測試工具

          這里我們需要下載 ChromeDriver 這個插件,當然這里是默認大家使用的是 Chrome 瀏覽器,如果是其他的瀏覽器,firefox,safari 等等,直接去網上找到相應 Driver 就可以了。

          這里給出 ChromeDriver 的下載地址

          http://npm.taobao.org/mirrors/chromedriver/

          大家一定要下載和自己 Chrome 瀏覽器版本一致的 ChromeDriver,不然程序是運行會報錯

          我們先不急著馬上開始爬取,我們先來嘗試使用一下Selenium調用ChromeDriver

          import requests
          from selenium import webdriver
          url = 'https://wenku.baidu.com/view/5292b2bc0166f5335a8102d276a20029bd64638c.html?fr=search'
          driver = webdriver.Chrome(r'F:\driver\chromedriver.exe')
          driver.get(url)
          

          怎么樣,是不是瀏覽器自動打開了? 現在我們嘗試輸出這個 driver,就可以看見,網頁的正確源代碼已經在里面了

          現在我們仔細研究一下源代碼就可以看到,我們需要的內容在下面這個位置

          現在正確的源代碼也有了,內容的位置也知道了,直接解析,爬取,完事就好了。

          想得美,經過這樣的爬取之后,對內容進行解析,讓我們看看究竟爬到沒有

          from lxml import etree
          import re
          html=etree.HTML(driver.page_source)
          links=html.xpath("//div[@class='reader-pic-item']/@style")
          part = re.compile(r'url[(](.*?)[)]')
          qa="".join(links)
          z=part.findall(qa)
          z
          

          我們可以知道,其實我們只爬到 3 張 PDF,其他的都沒有爬到。

          這是為什么呢?

          這是百度文庫為了防止大家去爬,專門設置的一個小機關

          返回百度文庫,我們仔細看看源代碼,其實我們可以發現,隨著頁面的變化,源代碼是不斷改變的,每次都只有 3 張圖片的 url。

          并且這個頁碼數也有一定的規律,如果在第二頁,那么圖片就是 1,2,3,如果在第三頁,圖片就是 2,3,4

          那么我們的疑惑一下就解決了,只需要不斷地進行換頁的爬取,就可以了

          接下來就是如何實現換頁的操作了

          這個需要兩個步驟,先是點擊繼續閱讀,然后進行頁面輸入實現換頁。

          先實現點擊的操作,代碼如下:

          button = driver.find_element_by_xpath("//*[@id='html-reader-go-more']/div[2]/div[1]/span")
          button.click()
          driver.execute_script("arguments[0].click();", button)
          

          整個操作是通過 JS 來進行的,大家可以把這個記住,以后需要點擊的時候直接用就可以

          然后就是輸入頁面實現換頁,這個其實涉及的比較多,細分的話,步驟分為獲取總頁數,依次輸入頁面并點擊。

          import re
          # 尋找頁面
          source = re.compile(r'<span class="page-count">/(.*?)</span>')
          number = int(source.findall(driver.page_source)[0])
          # 輸入頁面并點擊
          driver.find_element_by_class_name("page-input").clear()
          driver.find_element_by_class_name("page-input").send_keys('2')
          driver.find_element_by_class_name("page-input").send_keys(Keys.ENTER)
          

          如果小伙伴成功實現了上面的操作,其實大體的爬取工作已經差不多了,接下來就是保存我們的 PPT 和 PDF了

          因為爬取 PDF 和 PPT 的時候,我們是爬取的圖片的源地址,那么我們要獲得這張圖片并保存下來就必須對這個地址發起請求,然后將返回頭以二進制保存下來。

          for m in range(3):
              pic = requests.get(z[m]).content
              # 方法一
          #     file = open(f'./照片/{m+1}.jpg','wb')
          #     file.write(pic)
          #     file.close()
              # 方法二
              with open(f'./照片/{m+1}.jpg','wb') as f:
                  f.write(pic)
                  f.close()
          

          在這里,提醒大家一下一定要按照對圖片用正確順序進行命名,因為后面保存為 PDF 的時候,需要排序

          在 py 文件的目錄下,大家就可以看見保存下來的圖片了

          最后一步,將圖片保存為 PDF

          from PIL import Image
          import os
          folderPath = "F:/TEST"
          filename = "test"
          files = os.listdir(folderPath)
          jpgFiles = []
          sources = []
          for file in files:
              if 'jpg' in file:
                  jpgFiles.append(file)
          tep = []
          for i in jpgFiles:
              ex = i.split('.')
              tep.append(int(ex[0]))
          tep.sort()
          jpgFiles=[folderPath +'/'+ str(i) + '.jpg' for i in tep]
          output = Image.open(jpgFiles[0])
          jpgFiles.pop(0)
          for file in jpgFiles:
             img = Image.open(file)
             img = img.convert("P")
             sources.append(img)
          output.save(f"./{filename}.pdf","PDF",save_all=True,append_images=sources)
          

          最終的結果就是生成了咱們的 PDF 文件

          上述的操作看起來很多,很麻煩,其實并不是的,因為大部分的操作都是固定的,大家只需要記熟就可以了。

          簡單的 GUI 制作

          GUI 這塊,我們整了點新活兒,用 C# 編寫 winform 簡易的 GUI,調用爬蟲的 Py thon 代碼

          C# 調用 python 項目的方式我簡單用 Process 類執行,通過執行 python.exe 執行代碼

          public static void RunPythonScript(string sArgName, string py, string args = "", params string[] teps)
          {
              Process p = new Process();
          
              //(沒放debug下,寫絕對路徑)
              //string path = @"C:\Users\zll\Desktop\baidu\CSharpCallPython\bin\Debug\" + sArgName;
              // 獲得python文件的絕對路徑(將文件放在c#的debug文件夾中可以這樣操作)
              string path = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + sArgName;
          
              //沒有配環境變量的話,可以像我這樣寫python.exe的絕對路徑。如果配了,直接寫"python.exe"即可
              //p.StartInfo.FileName = @"C:\Users\zll\AppData\Local\Programs\Python\Python37-32\python.exe";
              p.StartInfo.FileName = @py;
              string sArguments = path;
          
              foreach (string sigstr in teps)
              {
                  sArguments += " " + sigstr;//傳遞參數
              }
          
              sArguments += " " + args;
          
              p.StartInfo.Arguments = sArguments;
              p.StartInfo.UseShellExecute = false;
              p.StartInfo.RedirectStandardOutput = true;
              p.StartInfo.RedirectStandardInput = true;
              p.StartInfo.RedirectStandardError = true;
              p.StartInfo.CreateNoWindow = true;
          
              p.Start();
              p.BeginOutputReadLine();
              p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
              Console.ReadLine();
              p.WaitForExit();
          }
          

          對輸入 的內容進行簡單判斷,如果不是百度文庫地址或不是 python.exe 地址,報錯

          if (!url.Contains("https://wenku.baidu.com/view/"))
          {
              MessageBox.Show("請輸入正確的百度文庫網址!");
              lbl_state.Text = "請重新輸入。";
          }
          else if (!py.Contains("python.exe"))
          {
              MessageBox.Show("請輸入正確的python.exe路徑!");
              lbl_state.Text = "請重新輸入。";
          }
          else
          {
              //輸入參數列表
              String[] strArr = new String[] { url, istxt };
              string sArguments = @"src\wenku.py";//這里是python的文件名字
              RunPythonScript(sArguments, py, "-u", strArr);
              if(result.Contains("0"))
                  lbl_state.Text = "對不起,爬取失敗。";
              else if (result.Contains("1"))
                  lbl_state.Text = "爬取成功!";
          }
          

          因為 GUI 部分比較簡單,這里就不過多描述了。

          、使用性能測試工具dotTrace 3.0,它能夠計算出你程序中那些代碼占用內存較多(下載網址:http://www.xue51.com/soft/4836.html)

          2、強制垃圾回收

          3、多dispose,close

          4、用timer,每幾秒鐘調用:SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);具體見附錄。

          5、發布的時候選擇Release

          6、注意代碼編寫時少產生垃圾,比如String + String就會產生大量的垃圾,可以用StringBuffer.Append

          7、this.Dispose(); this.Dispose(True); this.Close(); GC.Collect();

          8、注意變量的作用域,具體說某個變量如果只是臨時使用就不要定義成成員變量。GC是根據關系網去回收資源的。

          9、檢測是否存在內存泄漏的情況,詳情可參見:內存泄漏百度百科

          定期清理執行垃圾回收代碼:

          #region 內存回收
          [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
          public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);
          /// <summary>
          /// 釋放內存
          /// </summary>
          public static void ClearMemory()
          {
          GC.Collect();
          GC.WaitForPendingFinalizers();
          if (Environment.OSVersion.Platform == PlatformID.Win32NT)
          {
          App.SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
          }
          }
          #endregion

          (轉自:www.cnblogs.com的心存善念,至于他轉的那里,我就不知道了。。。。)


          主站蜘蛛池模板: 日本精品一区二区三区视频| 国产精品丝袜一区二区三区| 久久精品国产一区二区三区日韩| 91精品一区二区综合在线| 国产精品熟女视频一区二区 | 91精品福利一区二区三区野战| 无码人妻av一区二区三区蜜臀| 亚洲一区二区三区首页| 一区二区三区精品高清视频免费在线播放 | 亚洲国产精品一区二区久久| 一区二区三区四区在线播放| 国产福利酱国产一区二区| 亚洲av乱码一区二区三区香蕉| 国产亚洲综合一区柠檬导航 | 少妇人妻精品一区二区三区| 精品国产AⅤ一区二区三区4区| 国产一区二区在线观看麻豆| 最新中文字幕一区| 亚洲AV成人一区二区三区观看| 精品人妻系列无码一区二区三区| 日本免费一区二区久久人人澡| 少妇无码AV无码一区| 三上悠亚一区二区观看| 亚洲熟女一区二区三区| 亚洲一区二区三区自拍公司| 亚洲熟妇av一区二区三区 | 久久精品国产一区| 日韩视频一区二区三区| 日本一区二区不卡在线| 美女一区二区三区| 日韩精品乱码AV一区二区| 无码人妻精品一区二区三| 日韩免费无码一区二区三区 | 国产伦精品一区二区三区精品| 久久精品无码一区二区三区免费 | 又紧又大又爽精品一区二区| 视频一区二区在线播放| 精品久久国产一区二区三区香蕉| 久久综合精品国产一区二区三区| 丝袜人妻一区二区三区网站| 伊人色综合一区二区三区 |