分類
软件

PHP Development Tools——Eclipse

之前用NetBeans寫PHP倒也沒什麼問題,最近看到PSR-2的代碼編寫規範,覺得很好,但是NetBeans好像沒有找到設置的地方。搜了下PHP Development Tools (PDT)直接支持PSR-2。Sublime Text 2的編碼主題比較舒服,PDT也是有的,Sublime Text 2 theme for PDT下載。推薦下載EPF格式,然後在eclipse中File/Import/General/Preferences導入即可。爲了遵循PSR的代碼書寫規範,還需在Window/Preferences中進行如下設置:

  1. PHP/Code Style/Formatter/Active profile設置爲PSR-2。
  2. General/Workspace/New text file line delimiter設置爲Other:Unix。
  3. General/Editors/Text Editors勾選Show line margin,值設爲80。
分類
程序

python3字符串自增

週末喝恆大冰泉,發現掃二維碼中獎概率頗高,而且可以中獎金額直接用來給手機充值或提現到銀行卡,做的比較好。趁理髮無聊的時候寫了段python掃了一會兒,但是空手而歸。代碼也很簡單和用Python抓取大衆點評的用戶評論差不多,主要就是字符串自增這塊用了個遞歸:

from bs4 import BeautifulSoup import string,sys,time,random,urllib,http.cookiejar,socket #url="https://sao.so/t/dSTUVvjUhPHpz" baseDir="/storage/sdcard0/com.hipipal.qpyplus/scripts3/test/" base="_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" HDcode="dSTUVvjUhPIjL" bingoNo=0 failNo=0 def increase(s): sHead=s[0:-1] sFoot=s[-1:] sNew="" if(sFoot != "Z"): index=base.index(sFoot) sFootNew=base[index+1] sNew=sHead+sFootNew else: sHeadNew=increase(sHead) sFootNew="_" sNew=sHeadNew+sFootNew return sNew def getHTML(url): request = urllib.request.Request(url) request.add_header("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0") try: response = urllib.request.urlopen(request) except (urllib.error.HTTPError, socket.error,urllib.error.URLError) as e: print('Connection error occurred when inserting data.'+str(e)) else: if response.code != 200: print("Error code:"+response.code) else: html = response.read().decode('utf-8') return html def check(html): global bingoNo global failNo #with open(baseDir+'expired.html',encoding='utf-8') as html: soup = BeautifulSoup(html) images = soup.find_all('img') for image in images: if "errorQrCode.jpg" in image.get('src') : failNo = failNo + 1 print("fake: " + HDcode + " " + str(failNo)) break elif "冰泉君已经失身啦" in soup.get_text(): print("expired" + HDcode) break else: print("bingo" + HDcode) bingoNo = bingoNo + 4 if __name__ == '__main__': #html=getHTML(url) #with open(baseDir+'fake.html', mode='w', encoding='utf-8') as html_file: #html_file.write(html) global HDcode while(bingoNo < 2): url = "https://sao.so/t/" + HDcode html = getHTML(url) check(html) HDcode = increase(HDcode) time.sleep(random.randrange(4,7)) [/code]

其實命中的概率真的非常低,拿13位編碼來說,一共有(11+26+26)^13=2.46*10^23種組合,瓶子上說中獎概率33.3%,按300億銷售目標和5元均價算,一共有2×10^10瓶是可以中獎的。除一下就發現……不用除了吧

分類
网站

寬屏圖片居中的兩種方法

現在有些網站比較流行用100%寬度的圖片(div)佔滿屏幕,來營造出比較整體或是大氣的感覺。如果直接放一張大圖進去並禁止縮放,會發現瀏覽器是從圖片左側開始展示圖片,而我們想要的是主要顯示中間重要部分。有兩種方法可以做到,一種是利用CSS的背景居中,另一種是用js調整圖片的位置。Talking is cheap, here comes the code:

<style>
.wideBanner {background: rgba(0, 0, 0, 0) url("../images/bg.jpg") no-repeat scroll center center;height: 19px;}
</style>
<div id="wideBanner"></div>
<script type="text/javascript"> 
    $(document).ready(function(){
        var offset=($(window).width()-$("#wideBanner").css("width"))/2;
        $("#wideBanner").css("left",offset);
});
</script>
<div id="wideBanner"></div>

未知寬度div居中https://github.com/simaQ/cssfun/issues/3

     .container{width:500px;height:80px;background:#C2300B;margin-left:50px;padding-top:10px;text-align:center;}
     .center{display:inline-block;border:2px solid #fff;}
     .center{_display:inline;} /*针对ie6 hack*/
     .center a{float:left;border:1px solid #fff;padding:5px 10px;margin:10px;color:#fff;text-decoration:none;}
     <div class="container">
     <div class="center"><a href="#">1</a><a href="#">2</a><a href="#">3</a>
     <div style="clear:both"></div></div> 

本文更新於 2015/12/11。

分類
软件

安卓電話錄音軟件Automatic Call Recorder

Automatic Call Recorder

以前用HTC安卓2.3的時候找過電話錄音軟件,基本都是錄的外放的聲音,聽筒的人聲極小。而這款Automatic Call Recorder是有很多錄音線路可供選擇的,前面的都失敗後纔會選擇揚聲器模式。我在Sony Z上全部默認設置,錄下的聲音有電流聲干擾,但人聲還挺清晰,已經能作爲一個普通的電話錄音軟件來使用。有空再事實其他音源。

分類
方法

Windows設置

使用數位板時關閉水紋特效。運行gpedit.msc,用戶配置/管理模板/Windows組件/Tablet PC/光標,雙擊關閉筆反饋,選擇已啓用即可。

Window 10 文件管理器直接打開我的電腦(C、D盤界面,不是庫界面)可以這麼設置:菜單欄點 View > 右側 Options。在新開的設置窗口中 General 標籤頁下第一個設置項選擇「This PC」套用即可。Win7 先關閉文件管理器,然後按着Shift鍵,右鍵點擊快捷啓動欄到的文件管理器圖標,選屬性,修改快捷方式標籤頁中“目標”值爲“%windir%\explorer.exe ,”,即在原值後添加半角的空格和逗號。保存之後再點擊文件管理器打開的就是我的電腦了。

還是文件管理器,如果不常用左側的導航窗格,可以在左上角選組織/佈局來控制其顯示。其中還可以配置菜單欄、細節窗口和預覽窗口。

最近穿牆阻力大增,小紅傘升級艱難,試了下微軟官方到MSE,也挺好用的。其實平常自己注意下上網習慣,比裝個厲害到殺毒軟件重要。後來我轉到了免費的 COMODO Firewall。

win10 的微軟拼音抽風的把翻頁鍵設置成了[],如果想改回,.翻頁,需要修改註冊表。按 Windows鍵 + r 然後輸入 regedit 敲回車。在註冊表編輯器中依次打開 HKEY_CURRENT_USER\Software\Microsoft\InputMethod\CandidateWindow\CHS\1。在右側空白處按右鍵 New > DWORD (32bit) Value。名字輸入 CustomizedPagingKey ,然後雙擊剛剛建立的 CustomizedPagingKey ,Value data 輸入 f0f ,OK。更多 win10 微軟拼音輸入法的設置請參考:Win10微软拼音输入法设置-注册表

本文更新於 2020/11/03。

分類
方法

在電腦上調試火狐安卓版網頁

前兩天發現之前寫的在線小六壬有個重大問題,在火狐安卓版上算出的數據是錯的!經過一番查看瞭解到火狐安卓版時間選擇期發送的日期格式是“2015-05-19+12:39”這樣,而其他主流瀏覽器都是“2015-05-19T12:39”這樣,於是導致在解析收到的時間時發生錯誤。經過測試用數組炸開日期字符串時一共用需要("-","T",":","+"," ")這幾個,加號和空格都是爲了能讓火狐網頁版正常工作。詳細代碼在Github小六壬

下面說下用PC調試火狐手機端網頁。先在電腦端火狐中安裝Firefox OS Simulator。然後跟着Debugging Firefox for Android with WebIDE一步一步來就可以了,很簡單。

分類
程序

用Python抓取大衆點評的用戶評論

大衆點評的知识产权声明可真是霸道啊!還是自己先保存一份。下面代碼先將評論及商戶保存到sqlite數據庫,如果需要還可以導出成CSV,這樣辦公軟件就能直接打開查看了。

from bs4 import BeautifulSoup
import sys,time,random,urllib,http.cookiejar,socket,sqlite3,csv


goOn=1
stopDate=''
UserID=''
review={'shopName':'','shopAddr':'','shopURL':'','reviewURL':'','star':'',
'starDetail':'','costPerPeople':'','reviewText':'','dishes':'','reviewTime':''}

def getHTML(url):
  print("Fetching "+url)
  request = urllib.request.Request(url)
  request.add_header("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0")
  try:
    response = urllib.request.urlopen(request)
  except (urllib.error.HTTPError, socket.error,urllib.error.URLError) as e:
    print('Connection error occurred when inserting data.'+str(e))
  else:
    if response.code != 200:
      print("Error code:"+response.code)  
    else:
      html = response.read().decode('utf-8')
      return html

def getList(url):
  global review,goOn
  reviewList=getHTML(url)
  soupAll = BeautifulSoup(reviewList).find_all("div",{"class":"txt J_rptlist"})

  for soup in soupAll:
    shopLink = soup.find("a",{"class":"J_rpttitle"})
    review['shopName']=shopLink.text
    review['shopURL']=shopLink.get("href")
    
    shopAddr = soup.find("p",{"class":"col-exp"})
    review['shopAddr']=shopAddr.text
    
    reviewID = soup.find("a",{"class":"J_flower aheart"})
    review['reviewURL']="http://www.dianping.com/review/"+reviewID.get("data-id")
    
    reviewDateDiv = soup.find("div",{"class":"mode-tc info"})
    reviewDateSpan=reviewDateDiv.find("span",{"class":"col-exp"})
    reviewDate=str(reviewDateSpan.text)[3:]
    if(len(reviewDate)==8 and reviewDate>stopDate):
      getReview(review['reviewURL'])
      #抓取頻率
      time.sleep(random.randrange(5,10))
    else:
      goOn=0
  if(goOn==0):
    print("Finished.")
    exit()
    
      
    

def save():
  global review,UserID
  conn = sqlite3.connect('DZDB_'+UserID+'_Reviews.db')
  c = conn.cursor()
  c.execute("""create table if not exists reviews (ID integer primary key not NULL,shopName char(50),shopAddr char(100),shopURL char(100),reviewURL char(100),star char(1),starDetail char(15),costPerPeople char(15),reviewText TEXT,dishes char(100),reviewTime char(20))""")
  s="""insert into reviews (ID,shopName,shopAddr,shopURL,reviewURL,star,starDetail,costPerPeople,reviewText,dishes,reviewTime) VALUES (NULL,\'"""+review['shopName']+'\',\''+review['shopAddr']+'\',\''+review['shopURL']+'\',\''+review['reviewURL']+'\',\''+str(review['star'])+'\',\''+review['starDetail']+'\',\''+review['costPerPeople']+'\',\''+review['reviewText']+'\',\''+review['dishes']+'\',\''+review['reviewTime']+'\')'
  c.execute(s)
  conn.commit()
  c.close
  print("Record at "+review['shopName']+" saved to Datebase.")
  review={'shopName':'','shopAddr':'','shopURL':'','reviewURL':'','star':'',
'starDetail':'','costPerPeople':'','reviewText':'','dishes':'','reviewTime':''}

def getReview(url):
  global review
  reviewHTML=getHTML(url)
  reviewAll=BeautifulSoup(reviewHTML)
  shopInfo= reviewAll.find("ul",{"class":"contList-info"})
  star=str(shopInfo.find("li"))
  if("msstar50" in star):
    review['star']=5
  elif ("msstar40" in star):
    review['star']=4
  elif ("msstar30" in star):
    review['star']=3
  elif ("msstar20" in star):
    review['star']=2
  elif ("msstar10" in star):
    review['star']=1
  else:
    review['star']=0
  starDetails=shopInfo.find_all("span",{"class":"rst"})
  starDetail=""
  for s in starDetails:
    s1=s.text[0:3]
    starDetail=starDetail+s1
  review['starDetail']=starDetail
  
  reviewText= reviewAll.find("div",{"class":"contList-con"})
  review['reviewText']=reviewText.text
  units= reviewAll.find_all("div",{"class":"comment-unit"})
  for unit in units:
    unit=str(unit.text).replace('\n','')
    if("人均:" in unit):    
      review['costPerPeople']=unit[4:]
    elif("喜欢的菜:" in unit): 
      unit=unit.replace(' ','')
      unit=unit.replace('\xa0',' ')
      review['dishes']=unit[7:]
    
  reviewInfo= reviewAll.find("ul",{"class":"contList-fn"})  
  reviewTime=reviewInfo.find("li")
  review['reviewTime']=reviewTime.text
  save() 

def main():
  fun=int(input("请输入数字选择功能:\n[1]抓取数据,[2]导出数据: \n"))
  if(fun==1):
    fetchReview()
  elif(fun==2):
    sqliteToCSV()
  else:
    print("请输入1或2。")

    
def sqliteToCSV():
  dbFile=str(input("请输入数据库文件名:\n"))
  with open(dbFile+'.csv','w+',newline='') as csvfile:
    spamwriter = csv.writer(csvfile)
    conn=sqlite3.connect(dbFile)
    c = conn.cursor()
    spamwriter.writerow(['ID','shopName','shopAddr','shopURL','reviewURL','star',
'starDetail','costPerPeople','reviewText','dishes','reviewTime'])
    for row in c.execute('SELECT * FROM reviews'):
      spamwriter.writerow(row)
    c.close()
    print("CSV文件成功導出。")
    
def fetchReview():
  #抓取参数:用户ID,起始页,结束日期
  global stopDate,UserID
  UserID=str(input("请输入您的大众点评ID,可以在您大众点评主页的网址中看到,如23262500:\n"))
  startPageNo=int(input("开始的页码,如1:\n"))
  stopDate=str(input("请输入评论结束日期(yy-mm-dd),如00-00-00:\n"))
  
  urlBase="http://www.dianping.com/member/"+UserID+"/reviews?pg="
  startPageNo=startPageNo-1
  while(goOn==1):
    startPageNo=startPageNo+1
    getList(urlBase+str(startPageNo))
    
if __name__ == "__main__":
    main()
幾點說明
  • 抓取頻率不要過大,否則大衆點評會屏蔽IP。我在抓取到20頁左右的時候碰到過一次屏蔽IP。如果意外中斷,你可以設置參數繼續下載,附w3school的SQL基礎教程
  • BeautifulSoup真是個好工具,連Qpython3都自帶了,但是遺憾的是這個代碼在Qpython3上跑報NoneType錯誤。
  • 我用了幾次都沒問題。