Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲第一区第二区,中文字幕在线看视频一区二区三区 ,24式性无遮挡免费视频

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          Python 爬蟲之request+beautifu

          Python 爬蟲之request+beautifulsoup+mysql

          、什么是爬蟲?
          它是指向網(wǎng)站發(fā)起請求,獲取資源后分析并提取有用數(shù)據(jù)的程序;
          爬蟲的步驟:

          1、發(fā)起請求
          使用http庫向目標(biāo)站點發(fā)起請求,即發(fā)送一個Request
          Request包含:請求頭、請求體等

          2、獲取響應(yīng)內(nèi)容
          如果服務(wù)器能正常響應(yīng),則會得到一個Response
          Response包含:html,json,圖片,視頻等

          3、解析內(nèi)容
          解析html數(shù)據(jù):正則表達(dá)式(RE模塊),第三方解析庫如Beautifulsoup,pyquery等
          解析json數(shù)據(jù):json模塊
          解析二進(jìn)制數(shù)據(jù):以wb的方式寫入文件

          4、保存數(shù)據(jù)
          數(shù)據(jù)庫(MySQL,Mongdb、Redis)文件


          二、本次選擇爬蟲的數(shù)據(jù)來源于鏈家,因為本人打算搬家,想觀察一下近期的鏈家租房數(shù)據(jù)情況,所以就直接爬取了鏈家數(shù)據(jù),相關(guān)的代碼如下:

          from bs4 import BeautifulSoup as bs
          from requests.exceptions import RequestException
          import requests
          import re
          from DBUtils import DBUtils
          
          
          def main(response): #web頁面數(shù)據(jù)提取與入庫操作
              html=bs(response.text, 'lxml')
              for data in html.find_all(name='div',attrs={"class":"content__list--item--main"}):
                  try:
                      print(data)
                      Community_name=data.find(name="a", target="_blank").get_text(strip=True)
                      name=str(Community_name).split(" ")[0]
                      sizes=str(Community_name).split(" ")[1]
                      forward=str(Community_name).split(" ")[2]
                      flood=data.find(name="span",class_="hide").get_text(strip=True)
                      flood=str(flood).replace(" ","").replace("/","")
                      sqrt=re.compile("\d\d+㎡")
                      area=str(data.find(text=sqrt)).replace(" ","")
                      maintance=data.find(name="span",class_="content__list--item--time oneline").get_text(strip=True)
                      maintance=str(maintance)
                      price=data.find(name="span",class_="content__list--item-price").get_text(strip=True)
                      price=str(price)
                      print(name,sizes,forward,flood,maintance,price)
                      insertsql="INSERT INTO test_log.`information`(Community_name,size,forward,area,flood,maintance,price) VALUES " \
                      "('"+name+"','"+sizes+"','"+forward+"','"+area+"','"+flood+"','"+maintance+"','"+price+"');"
                      insert_sql(insertsql)
                  except:
                      print("have an error!!!")
          
          
          def insert_sql(sql): #數(shù)據(jù)入庫操作
              dbconn=DBUtils("test6")
              dbconn.dbExcute(sql)
          
          
          def get_one_page(urls): #獲取web頁面數(shù)據(jù)
              try:
                  headers={"Host": "bj.lianjia.com",
                        "Connection": "keep-alive",
                        "Cache-Control": "max-age=0",
                        "Upgrade-Insecure-Requests": "1",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36",
                        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                        "Sec-Fetch-Site": "none",
                        "Sec-Fetch-Mode": "navigate",
                        "Sec-Fetch-User": "?1",
                        "Sec-Fetch-Dest": "document",
                        "Accept-Encoding": "gzip, deflate, br",
                        "Accept-Language": "zh-CN,zh;q=0.9",
                        "Cookie": "lianjia_uuid=fa1c2e0b-792f-4a41-b48e-78531bf89136; _smt_uid=5cfdde9d.cbae95b; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2216b3fad98fc1d1-088a8824f73cc4-e353165-2710825-16b3fad98fd354%22%2C%22%24device_id%22%3A%2216b3fad98fc1d1-088a8824f73cc4-e353165-2710825-16b3fad98fd354%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E8%87%AA%E7%84%B6%E6%90%9C%E7%B4%A2%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%22%2C%22%24latest_referrer_host%22%3A%22www.baidu.com%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%7D%7D; _ga=GA1.2.1891741852.1560141471; UM_distinctid=17167f490cb566-06c7739db4a69e-4313f6b-100200-17167f490cca1e; Hm_lvt_9152f8221cb6243a53c83b956842be8a=1588171341; lianjia_token=2.003c978d834648dbbc2d3aa4b226145cd7; select_city=110000; lianjia_ssid=fc20dfa1-6afb-4407-9552-2c4e7aeb73ce; CNZZDATA1253477573=1893541433-1588166864-https%253A%252F%252Fwww.baidu.com%252F%7C1591157903; CNZZDATA1254525948=1166058117-1588166331-https%253A%252F%252Fwww.baidu.com%252F%7C1591154084; CNZZDATA1255633284=1721522838-1588166351-https%253A%252F%252Fwww.baidu.com%252F%7C1591158264; CNZZDATA1255604082=135728258-1588168974-https%253A%252F%252Fwww.baidu.com%252F%7C1591153053; _jzqa=1.2934504416856578000.1560141469.1588171337.1591158227.3; _jzqc=1; _jzqckmp=1; _jzqy=1.1588171337.1591158227.1.jzqsr=baidu.-; _qzjc=1; _gid=GA1.2.1223269239.1591158230; _qzja=1.1313673973.1560141469311.1588171337488.1591158227148.1591158227148.1591158233268.0.0.0.7.3; _qzjto=2.1.0; srcid=eyJ0Ijoie1wiZGF0YVwiOlwiMThmMWQwZTY0MGNiNTliNTI5OTNlNGYxZWY0ZjRmMmM3ODVhMTU3ODNhNjMwODhlZjlhMGM2MTJlMDFiY2JiN2I4OTBkODA0M2Q0YTM0YzIyMWE0YzIwOTBkODczNTQwNzM0NTc1NjBlM2EyYTc3NmYwOWQ3OWQ4OWJjM2UwYzAwY2RjMTk3MTMwNzYwZDRkZTc2ODY0OTY0NTA5YmIxOWIzZWQyMWUzZDE3ZjhmOGJmMGNmOGYyMTMxZTI1MzIxMGI4NzhjNjYwOGUyNjc3ZTgxZjA2YzUzYzE4ZjJmODhmMTA1ZGVhOTMyZTRlOTcxNmNiNzllMWViMThmNjNkZTJiMTcyN2E0YzlkODMwZWIzNmVhZTQ4ZWExY2QwNjZmZWEzNjcxMjBmYWRmYjgxMDY1ZDlkYTFhMDZiOGIwMjI2NTg1ZGU4NTQyODBjODFmYTUyYzI0NDg5MjRlNWI0N1wiLFwia2V5X2lkXCI6XCIxXCIsXCJzaWduXCI6XCI2Yzk3M2U5M1wifSIsInIiOiJodHRwczovL2JqLmxpYW5qaWEuY29tL2RpdGllenVmYW5nL2xpNDY0NjExNzkvcnQyMDA2MDAwMDAwMDFsMSIsIm9zIjoid2ViIiwidiI6IjAuMSJ9"}
                  response=requests.get(url=urls, headers=headers)
                  main(response)
              except RequestException:
                  return None
          
          
          if __name__=="__main__":
                for i in range(64): #遍歷翻頁
                  if(i==0):
                      urls="https://bj.lianjia.com/ditiezufang/li46461179/rt200600000001l1/"
                      get_one_page(urls)
                  else:
                      urls="https://bj.lianjia.com/ditiezufang/li46461179/rt200600000001l1/".replace("rt","pg"+str(i))
                      get_one_page(urls)

          說明:本代碼中使用了《Python之mysql實戰(zhàn)》的那篇文章,請注意結(jié)合著一起來看。


          三、以下是獲取到的數(shù)據(jù)入庫后的結(jié)果圖

          結(jié)論:爬蟲是獲取數(shù)據(jù)的重要方式之一,我們需要掌握多種方式去獲取數(shù)據(jù)。機(jī)器學(xué)習(xí)是基于數(shù)據(jù)的學(xué)習(xí),我們需要為機(jī)器學(xué)習(xí)做好數(shù)據(jù)的準(zhǔn)備,大家一起加油!

          提:

          mysql自己的參數(shù)生成html,不盡人意......

          mysql -h$host -u$user -p$pass -H --skip-column-names $database -e "source get_query.sql" > /tmp/query.html

          1、熱身一下,巧用awk構(gòu)造mysql測試數(shù)據(jù)

          #/bin/sh

          echo "line" > file.dat

          echo "" > insert.sql

          awk 'BEGIN{

          system("echo \"create table sysbench (col1 INT, col2 INT,col3 INT);\" | mysql -uroot -p123456 taobao")

          for (i=1; i<=100; i++)

          {

          print " insert into sysbench values (" i "," i*i "," i*i*i ");" >> "insert.sql"

          }

          }

          END{

          system("mysql -uroot -p123456 -D taobao < insert.sql")

          }' file.dat

          2、

          1)主要使用pt-query-digest來完成入庫操作

          192.168.0.2為慢查詢?nèi)霂斓臋C(jī)器

          pt-query-digest --user=dba --password=123456 --review h=192.168.0.2,D=slow_query,t=global_query_review --history h=192.168.0.2,D=slow_query,t=global_query_review_history --no-report --filter=" $event->{Bytes}=length($event->{arg}) and $event->{hostname}=\"`ifconfig eth1|grep "inet addr"|awk '{print }'|awk -F':' '{print ":3306"}'`\" " /data/3306/slow_query.log

          2)主要涉及到兩個表global_query_review和global_query_review_history,去percona官網(wǎng)copy創(chuàng)建或者pt工具自動創(chuàng)建

          計算下慢查詢排行,根據(jù)Query_time_pct_95來排序,并且生成html格式

          #/bin/sh

          mysql -uroot -p123456 slow_query -N -e "select db_max as DBname,ifnull(sum(ts_cnt),0) as Ts_cnt,sum(cast(Query_time_sum AS SIGNED )) as Query_time_sum,avg(cast(Query_time_pct_95 AS SIGNED )) as Avg_Query_time_pct_95,sum(cast(Lock_time_sum AS SIGNED )) as Lock_time_sum,sum(cast(Rows_sent_sum AS SIGNED )) as Rows_sent_sum,sum(cast(Rows_examined_sum AS SIGNED )) as Rows_examined_sum,sum(cast(Rows_affected_sum AS SIGNED )) as Rows_affected_sum,sum(ifnull(cast(Tmp_table_sum AS SIGNED ),0)) as Tmp_table_sum,sum(ifnull(cast(Filesort_sum AS SIGNED ),0)) as Filesort_sum,sum(ifnull(cast(Full_scan_sum AS SIGNED ),0)) as Full_scan_sum from global_query_review a,global_query_review_history b where a.checksum=b.checksum and db_max not in ('information_schema') and b.Query_time_pct_95 >=1 group by db_max order by Avg_Query_time_pct_95 desc;" >slow.txt

          echo "hello everybody:<table border=1><tr><td>Number</td><td>DBname</td><td>Ts_cnt</td><td>Query_time_sum</td><td>Avg_Query_time_pct_95</td><td>Lock_time_sum</td><td>Rows_sent_sum</td><td>Rows_examined_sum</td><td>Rows_affected_sum</td><td>Tmp_table_sum</td><td>Filesort_sum</td><td>Full_scan_sum</td>" >./query.html

          awk '{ print FNR " " >awk '{ print FNR " " $0 }' ./slow.txt | awk '{if (NR % 2==1) print "<tr style=\"background:#58ACFA\"><td>" $1 "</td><td align=\"left\">" $2 "</td><td align=\"left\">" $3 "</td><td align=\"left\">" $4 "</td><td align=\"left\">" $5 "</td><td align=\"left\">" $6 "</td><td align=\"left\">" $7 "</td><td align=\"left\">" $8 "</td><td align=\"left\">" $9 "</td><td align=\"left\">" $10 "</td><td align=\"left\">" $11 "</td><td align=\"left\">" $12 "</td></tr>";else print "<tr style=\"background:#F3E2A9\"><td>" $1 "</td><td align=\"left\">" $2 "</td><td align=\"left\">" $3 "</td><td align=\"left\">" $4 "</td><td align=\"left\">" $5 "</td><td align=\"left\">" $6 "</td><td align=\"left\">" $7 "</td><td align=\"left\">" $8 "</td><td align=\"left\">" $9 "</td><td align=\"left\">" $10 "</td><td align=\"left\">" $11 "</td><td align=\"left\">" $12 "</td></tr>";}' >> ./query.html< }' ./slow.txt | awk '{if (NR % 2==1) print "<tr style=\"background:#58ACFA\"><td>" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td></tr>";else print "<tr style=\"background:#F3E2A9\"><td>" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td><td align=\"left\">" "</td></tr>";}' >> ./query.html

          echo "</table>" >>./query.html

          cat query.html:

          hello everybody:<table border=1><tr><td>Number</td><td>DBname</td><td>Ts_cnt</td><td>Query_time_sum</td><td>Avg_Query_time_pct_95</td><td>Lock_time_sum</td><td>Rows_sent_sum</td><td>Rows_examined_sum</td><td>Rows_affected_sum</td><td>Tmp_table_sum</td><td>Filesort_sum</td><td>Full_scan_sum</td>

          <tr style="background:#58ACFA"><td>1</td><td align="left">dba</td><td align="left">0</td><td align="left">18</td><td align="left">6.0000</td><td align="left">0</td><td align="left">0</td><td align="left">2999532</td><td align="left">2999532</td><td align="left">0</td><td align="left">0</td><td align="left">0</td></tr>

          </table>

          3)最后一步,發(fā)送郵件,大功告成。

          /usr/bin/python sendmail.py aa@gmail.com Mysql Slowquery by Query_time_pct_95 >=1 ./query.html

          這樣就可以發(fā)送html郵件了。

          在前面

          覺得不錯的朋友可以讀完關(guān)注下,每周都有定期更新的精選內(nèi)容分享給大家,感謝您的支持!

          一、為什么難

          秒殺系統(tǒng)難做的原因:庫存只有一份,所有人會在集中的時間讀和寫這些數(shù)據(jù)。例如小米手機(jī)每周二的秒殺,可能手機(jī)只有1萬部,但瞬時進(jìn)入的流量可能是幾百幾千萬。又例如12306搶票,亦與秒殺類似,瞬時流量更甚。

          主要需要解決的問題有兩個:

          1. 高并發(fā)對數(shù)據(jù)庫產(chǎn)生的壓力
          2. 競爭狀態(tài)下如何解決庫存的正確減少(超賣問題)

          對于第一個問題,已經(jīng)很容易想到用緩存來處理搶購,避免直接操作數(shù)據(jù)庫,例如使用Redis。重點在于第二個問題,常規(guī)寫法:

          查詢出對應(yīng)商品的庫存,看是否大于0,然后執(zhí)行生成訂單等操作,但是在判斷庫存是否大于0處,如果在高并發(fā)下就會有問題,導(dǎo)致庫存量出現(xiàn)負(fù)數(shù)

          二、常見架構(gòu)

          流量到了億級別,常見站點架構(gòu)如上:

          1. 瀏覽器端,最上層,會執(zhí)行到一些JS代碼
          2. 站點層,這一層會訪問后端數(shù)據(jù),拼html頁面返回給瀏覽器
          3. 服務(wù)層,向上游屏蔽底層數(shù)據(jù)細(xì)節(jié)
          4. 數(shù)據(jù)層,最終的庫存是存在這里的,mysql是一個典型

          三、優(yōu)化方向

          1.將請求盡量攔截在系統(tǒng)上游:傳統(tǒng)秒殺系統(tǒng)之所以掛,請求都壓倒了后端數(shù)據(jù)層,數(shù)據(jù)讀寫鎖沖突嚴(yán)重,并發(fā)高響應(yīng)慢,幾乎所有請求都超時,流量雖大,下單成功的有效流量甚小【一趟火車其實只有2000張票,200w個人來買,基本沒有人能買成功,請求有效率為0】

          2.充分利用緩存:這是一個典型的讀多寫少的應(yīng)用場景【一趟火車其實只有2000張票,200w個人來買,最多2000個人下單成功,其他人都是查詢庫存,寫比例只有0.1%,讀比例占99.9%】,非常適合使用緩存。

          四、優(yōu)化細(xì)節(jié)

          4.1.瀏覽器層請求攔截

          點擊了“查詢”按鈕之后,系統(tǒng)那個卡呀,進(jìn)度條漲的慢呀,作為用戶,我會不自覺的再去點擊“查詢”,繼續(xù)點,繼續(xù)點,點點點。。。有用么?平白無故的增加了系統(tǒng)負(fù)載(一個用戶點5次,80%的請求是這么多出來的),怎么整?

          • 產(chǎn)品層面,用戶點擊“查詢”或者“購票”后,按鈕置灰,禁止用戶重復(fù)提交請求
          • JS層面,限制用戶在x秒之內(nèi)只能提交一次請求

          如此限流,80%流量已攔。

          4.2.站點層請求攔截與頁面緩存

          瀏覽器層的請求攔截,只能攔住小白用戶(不過這是99%的用戶喲),高端的程序員根本不吃這一套,寫個for循環(huán),直接調(diào)用你后端的http請求,怎么整?

          • 同一個uid,限制訪問頻度,做頁面緩存,x秒內(nèi)到達(dá)站點層的請求,均返回同一頁面
          • 同一個item的查詢,例如手機(jī)車次,做頁面緩存,x秒內(nèi)到達(dá)站點層的請求,均返回同一頁面

          如此限流,又有99%的流量會被攔截在站點層

          4.3.服務(wù)層請求攔截與數(shù)據(jù)緩存

          站點層的請求攔截,只能攔住普通程序員,高級黑客,假設(shè)他控制了10w臺肉雞(并且假設(shè)買票不需要實名認(rèn)證),這下uid的限制不行了吧?怎么整?

          • 大哥,我是服務(wù)層,我清楚的知道小米只有1萬部手機(jī),我清楚的知道一列火車只有2000張車票,我透10w個請求去數(shù)據(jù)庫有什么意義呢?對于寫請求,做請求隊列,每次只透有限的寫請求去數(shù)據(jù)層,如果均成功再放下一批,如果庫存不夠則隊列里的寫請求全部返回“已售完”
          • 對于讀請求,還要我說么?cache抗,不管是memcached還是redis,單機(jī)抗個每秒10w應(yīng)該都是沒什么問題的

          如此限流,只有非常少的寫請求,和非常少的讀緩存mis的請求會透到數(shù)據(jù)層去,又有99.9%的請求被攔住了

          4.4.數(shù)據(jù)層閑庭信步

          到了數(shù)據(jù)這一層,幾乎就沒有什么請求了,單機(jī)也能扛得住,還是那句話,庫存是有限的,小米的產(chǎn)能有限,透這么多請求來數(shù)據(jù)庫沒有意義。

          4.5.mysql批量入庫提高INSERT效率

          五、Redis

          使用redis隊列(list),push和pop操作保證了原子性的實現(xiàn)。即使有很多用戶同時到達(dá),也是依次執(zhí)行。(mysql事務(wù)在高并發(fā)下性能下降很厲害)

          先將商品庫存存入隊列:

          <?php 
          $store=1000; //商品庫存
          $redis=new Redis(); 
          $result=$redis->connect('127.0.0.1',6379); 
          $res=$redis->llen('goods_store'); 
          for($i=0; $i<$store; $i++){ 
           $redis->lpush('goods_store',1); 
          } 
          echo $redis->llen('goods_store'); 
          ?> 
          

          客戶執(zhí)行下單操作:

          $redis=new Redis(); 
          $result=$redis->connect('127.0.0.1',6379);
          $count=$redis->lpop('goods_store');
          if(!$count){
           echo '搶購失敗!';
           return;
          } 
          

          緩存也是可以應(yīng)對寫請求的,比如我們就可以把數(shù)據(jù)庫中的庫存數(shù)據(jù)轉(zhuǎn)移到Redis緩存中,所有減庫存操作都在Redis中進(jìn)行,然后再通過后臺進(jìn)程把Redis中的用戶秒殺請求同步到數(shù)據(jù)庫中

          六、總結(jié)

          沒什么總結(jié)了,上文應(yīng)該描述的非常清楚了,對于秒殺系統(tǒng),再次重復(fù)下兩個架構(gòu)優(yōu)化思路

          1. 盡量將請求攔截在系統(tǒng)上游
          2. 讀多寫少經(jīng)量多使用緩存
          3. redis隊列緩存 + mysql 批量入庫

          最后

          讀到這的朋友可以轉(zhuǎn)發(fā)支持下,同時可以關(guān)注我,每周都有定期更新的精選內(nèi)容分享給大家!


          主站蜘蛛池模板: 中文字幕在线播放一区| 88国产精品视频一区二区三区| 高清一区二区三区免费视频| 无码福利一区二区三区| 久久精品国产一区二区三区肥胖 | 中文字幕无码一区二区三区本日| 久久久久人妻精品一区三寸| 国产午夜精品免费一区二区三区 | 免费无码一区二区三区蜜桃大| 日韩人妻精品一区二区三区视频| 精品无码一区二区三区水蜜桃| 亚洲欧美一区二区三区日产| 亚洲av乱码一区二区三区香蕉| 日韩欧国产精品一区综合无码| 中文字幕精品亚洲无线码一区应用 | 高清一区二区三区免费视频| 东京热无码av一区二区| 久久成人国产精品一区二区| 无码人妻精品一区二区蜜桃AV| 内射少妇一区27P| 鲁大师成人一区二区三区| 国产中文字幕一区| 日韩精品电影一区亚洲| 福利视频一区二区牛牛| 亚洲av午夜精品一区二区三区| asmr国产一区在线| 国产日韩AV免费无码一区二区三区| 无码欧精品亚洲日韩一区夜夜嗨 | 日韩国产精品无码一区二区三区| 亚洲av综合av一区| 亚洲视频一区在线| 亚无码乱人伦一区二区| 日本一区二区三区精品视频| 美女福利视频一区二区| 无码日韩人妻AV一区免费l| 嫩B人妻精品一区二区三区| 久久久一区二区三区| 中文字幕乱码人妻一区二区三区| 99国产精品欧美一区二区三区| 国产精品综合一区二区三区| 精品91一区二区三区|