Tento článek je zrcadlovým článkem o strojovém překladu, klikněte zde pro přechod na původní článek.

Pohled: 13448|Odpověď: 5

Jak vědecky chytit červené obálky: Na konci roku můžete zbohatnout a napsat program, jak chytit červené obálky

[Kopírovat odkaz]
Zveřejněno 13.02.2015 22:44:10 | | | |
0×00 Pozadí

Jaké jsou ty červené obálky? Syn jeho bratra, Huer, řekl: "Peníze jsou téměř srovnatelné. Bratr a dcera Dao Yun řekli: "Není to tak dobré jako u mé tety kvůli větru." "Všichni chápou pozadí, je Nový rok a je den, kdy červené obálky létají po celé obloze. Náhodou jsem se před dvěma dny naučil Python a byl jsem nadšenější, takže jsem studoval a studoval prolézání červených obálek na Weibo, proč červené obálky na Weibo místo červených z Alipay, protože rozumím jen webu, a pokud budu mít energii, možná se v budoucnu začnu učit i algoritmus "vráť krtka".
Protože jsem začátečník v Pythonu, je to také třetí program, který jsem napsal po naučení Pythonu, takže prosím neptejte se osobně, pokud je v kódu nějaká chyba, důraz je na samotný nápad, ale pokud je v tom nějaká vada, prosím, nezkoušejte to osobně, vidíte, IE má tu tvář, že se nastaví jako výchozí prohlížeč, a když napíšu článek o špíně, je to také přijatelné......
Používám Python 2.7 a říká se, že mezi Pythonem 2 a Pythonem 3 je velký rozdíl.
0×01 Nápady
Byl jsem příliš líný to popsat slovy, tak jsem nakreslil skicu a všichni by to měli být schopni pochopit.
Za prvé, staré pravidlo: nejprve představte knihovnu, o které nevíte, že je užitečná, ale bez ní se nemůžete obejít –
[mw_shl_code=java,true]import re import urllib import urllib2 import cookielib import base64 import binascii import os import json import sys import cPickle as p import rsa[/mw_shl_code] Pak deklarujte další proměnné, které budete později potřebovat:

[mw_shl_code=java,true]reload(sys)sys.setdefaultencoding('utf-8&') #将字符编码置为utf-8luckyList=[] #红包列表lowest=10 #能忍受红包领奖记录最低为多少[/mw_shl_code]Zde se používá knihovna rsa, která není ve výchozím nastavení v Pythonu. Musím to nainstalovat :https://pypi.python.org/pypi/rsa/

Po stažení ho spustíme setpy.py nainstalujeme a pak můžeme začít s vývojem.
0×02 Přihlášení na Weibo
Akce uchopení červených obálek musí být provedena po přihlášení, takže musí existovat funkce přihlašování, přihlášení není klíč, klíčem je uchovávání cookies, zde je vyžadována spolupráce cookielib.
[mw_shl_code=java,true]cj = cookielib. CookieJar()opener = urllib2.build_opener(urllib2. HTTPCookieProcessor(cj))urllib2.install_opener(opener)[/mw_shl_code] Tímto způsobem všechny síťové operace pomocí openeru zvládnou stav cookies, i když o tom moc nevím, ale je to úžasný pocit.
Dále musíme zapouzdřit dva moduly, jeden je modul pro sběr dat, který slouží jednoduše k získání dat, a druhý pro POST data.
[mw_shl_code=java,true]def getData(url) : try: req = urllib2. Request(url) result = opener.open(req) text = result.read() text=text.decode("utf-8").encode("gbk",'ignore') vrátit text kromě výjimky, e:                Print u' request exception, URL: '+url print e def postData(url,data,header) : try: data = urllib.urlencode(data) req = urllib2. Request(url,data,header) result = opener.open(req) text = result.read() vrať text kromě výjimky, e: print u'Request exception, url: '+url[/mw_shl_code] S těmito dvěma moduly můžeme GET a POST data, přičemž důvod, proč getData dekóduje a pak kóduje, je ten, že ve Win7 jsem při ladění vždy zkresloval výstup, takže jsem přidal nějaké zpracování kódování, ale to není podstatné, funkce přihlášení níže je jádrem Weibo přihlášení.
[mw_shl_code=java,true]def login(nick, pwd): tisknout u"----------login----------" tisknout "----------......----------" prelogin_url= 'http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=%s&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.15)&_= 1400822309846' % nick preLogin = getData(prelogin_url) servertime = re.findall('"servertime":(.+?),' , preLogin)[0] pubkey = re.findall('"pubkey":"(.+?)",' , preLogin)[0] rsakv = re.findall('"rsakv":"(.+?)",' , preLogin)[0] nonce = re.findall('"nonce":"(.+?)",' , preLogin)[0] #print bytearray('xxxx','utf-8') su = base64.b64encode(urllib.quote(nick))        rsaPublickey = int(pubkey,16) key = rsa. PublicKey(rsaPublickey,65537) zpráva = str(servertime) +'\t' + str(nonce) + '\n' + str(pwd) sp = binascii.b2a_hex(rsa.encrypt(message,key)) hlavička = {'User-Agent' : 'Mozilla/5.0 (kompatibilní; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)'} param = { 'entry': 'weibo', 'gateway': '1', 'from': ''savestate': '7', 'userticket': '1',                'ssosimplelogin': '1', 'vsnf': '1', 'vsnval': ''', 'su': su, 'service': 'miniblog', 'servertime': servertime, 'nonce': nonce, 'pwencode': 'rsa2', 'sp': sp, 'encoding': 'UTF-8', 'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack', 'returntype': 'META', 'rsakv' : rsakv, } s = postData('http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)',param,header) try: urll = re.findall("locatio remove n.replace\(\'(.+?) \'\); " , s)[0] login=getData(urll) print u"--------- Přihlášení úspěšné! ------- "tisknout" ----------......---------- "kromě výjimky, e: vytisknout u" --------- přihlášení selhalo! -------" vytisknout "----------......----------" exit(0)[/mw_shl_code] Parametry a šifrovací algoritmy v tomto jsou zkopírované z internetu, moc tomu nerozumím, pravděpodobně je potřeba nejprve požádat o časové razítko a veřejný klíč, pak o RSA šifrování a nakonec zpracovat zpracování a odesílat do přihlašovacího rozhraní Sina, po úspěšném přihlášení ze Sina se vrátí Weibo adresa, kterou musíte požádat, aby se stav přihlášení plně uplatnil, Po úspěšném přihlášení budou další požadavky obsahovat cookie aktuálního uživatele.
0×03 Označený červený obrázek obálky
Po úspěšném přihlášení na Weibo se nemůžu dočkat, až najdu červenou obálku, kterou si to zkusím jako první, samozřejmě nejdřív v prohlížeči. Nakonec jsem našel stránku s červeným tlačítkem obálky, F12 vyvolal debugger, aby zjistil, co datový paket požaduje.

Vidíte, že adresa požadavku je http://huodong.weibo.com/aj_hongbao/getlucky, jsou tam dva hlavní parametry, jeden je ouid, tedy červené ID obálky, které je vidět v URL, druhý parametr share určuje, zda ho sdílet s Weibo, a je tu _t, ke kterému nevím, k čemu slouží.
Dobře, teoreticky můžete extrakci červených obálek dokončit zadáním tří parametrů do této URL, ale když parametry skutečně odešlete, zjistíte, že server vám zázračně vrátí takový řetězec:
[mw_shl_code=java, pravda] {"code":303403,"msg":"Omlouváme se, nemáte povolení k přístupu na tuto stránku","data":[]}[/mw_shl_code] Nepanikařte, podle mých mnohaletých zkušeností s webovým vývojem by měl programátor druhé strany posoudit referer, velmi jednoduše – zkopírovat všechny hlavičky předchozího požadavku.
[mw_shl_code=java,true]def getLucky(id): #抽奖程序 print u"--- draw red envelope from:"+str(id)+"---" print "----------......----------" if checkValue(id)==False: #不符合条件, toto je funkce return později        luckyUrl="http://huodong.weibo.com/aj_hongbao/getlucky" param={ 'ouid':id, 'share':0, '_t':0 } header= {                'Cache-Control':'no-cache', 'Content-Type':'application/x-www-form-urlencoded', 'Origin':'http://huodong.weibo.com', 'Pragma':'no-cache', 'Referer': 'http://huodong.weibo.com/hongbao/'+str(id), 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, podobně jako Gecko) Chrome/33.0.1750.146 BIDUBrowser/6.x Safari/537.36', 'X-Requested-With':'XMLHttpRequest' } res = postData(luckyUrl,param, hlavička)[/mw_shl_code] V tomto případě teoreticky problém neexistuje, ale ve skutečnosti žádný problém není. Po dokončení loterijní akce musíme posoudit stav a vrácená res je řetězec json, kde kód je 100000 je úspěšný, a pokud je to 90114, je to horní limit dnešní loterie, a ostatní hodnoty jsou také nesplněny, takže:
[mw_shl_code=java,true]hbRes=json.loads(res)if hbRes["code"]=='901114': #今天红包已经抢完 print u"--------- dosáhl horní hranice---------" print "----------......----------" log('lucky', str(id)+'---'+str(hbRes["code"])+'---'+hbRes["data"]["title"]) exit(0)elif hbRes["code"]=='1000000':#成功 print u"---------Přeji vám prosperitu---------" print "----------......----------"        log('success',str(id)+'---'+res) exit(0) if hbRes["data"] a hbRes["data"]["title"]: tisk hbRes["data"]["title"] tisk "----------......----------" log('lucky', str(id)+'---'+str(hbRes["code"])+'---'+hbRes["data"]["title"])else: print u"---------Request error---------" print "----------......----------" log('lucky', str(id)+'---'+res)[/mw_shl_code], kde log je také funkce, kterou si přizpůsobuji a která slouží k zaznamenávání logů:
[mw_shl_code=java,true]def log(type,text): fp = open(type+'.txt','a') fp.write(text) fp.write('\r\n') fp.close()[/mw_shl_code]





Předchozí:Poznámky k maximálním limitům pro upload v PHP
Další:Rozšíření memcache DLL ke stažení pro PHP5.2, 5.3, 5.4, 5.5
 Pronajímatel| Zveřejněno 13.02.2015 22:46:37 |
0×04 Prohledat seznam červených obálek
Po úspěšném testu jediné akce sběru červených obálek je to jádro modulu velkého tahu našeho programu – procházení seznamu červených obálek by mělo existovat mnoho metod a vstupů pro procházení seznamu červených obálek, například různá klíčová slova pro vyhledávání na Weibo a podobně, ale používám tu nejjednodušší metodu: procházení seznamu červených obálek.
Na domovské stránce (http://huodong.weibo.com/hongbao aktivity s červenými obálkami, přes různé další body, lze vše pozorovat, i když je seznam hodně propojený, lze jej shrnout do dvou kategorií (kromě nejbohatšího seznamu červených obálek): téma a žebříček.
Pokračujte ve vyvolávání F12, analyzujte formát obou stránek a začněte seznamem tematických forem, například: http://huodong.weibo.com/hongbao/special_quyu
Vidíte, že informace o červené obálce je v divu jménem info_wrap, takže stačí aktivovat zdrojový kód této stránky, pak stáhnout všechny infowrapy a jednoduše je zpracovat, abychom získali červený seznam obálek této stránky, zde potřebujeme použít nějaké reguláry:
[mw_shl_code=java,true]def getThemeList(url,p):#主题红包 print u"--------- "+str(p)+"page---------" print "----------......----------" html=getData(url+'?p='+str(p)) pWrap= re.compile(r'<div class="info_wrap">(.+?) <span class="rob_txt"></span>', re. DOTALL) #h Získejte info_wrap běžné pInfo=re.compile(r'.+<em class="num">(.+)</em>.+<em class="num">(.+)</em>.+<em class="num">(.+).</em>.+href="(.+)" class="btn"',re. DOTALL) #获取红包信息 List=pWrap.findall(html,re. DOTALL) n=len(Seznam) pokud n==0: vraťte pro i v rozsahu(n): #traverse všech info_wrap div s=pInfo.match(Seznam) #取得红包信息 info=list(s.groups(0))                info[0]=float(info[0].replace('\xcd\xf2','0000')) #现金,ten->0000 try: info[1]=float(info[1].replace('\xcd\xf2','0000')) #礼品价值 kromě Exception, e:                        info[1]=float(info[1].replace('\xd2\xda','00000000')) #礼品价值 info[2]=float(info[2].replace('\xcd\xf2','0000')) #已发送 if info[2]==0: info[2]=1 #防止除数为0 pokud info[1]==0: info[1]=1 #防止除数为0 info.append(info[0]/(info[2]+info[1])) #红包价值, hotovost/(počet získaných + hodnota výhry) # pokud info[0]/(info[2]+info[1])>100:                # print url luckyList.append(info) if 'class="page"' in html:#存在下一页 p=p+1 getThemeList(url,p) #递归调用自己爬取下一页[/mw_shl_code]Je tak těžké říct, že je to tak těžké, a trvalo dlouho napsat tyto dvě věty. V příloze [4] je také informace o tom, jak přibližně odhadnout hodnotu červených obálek, proč to dělat, protože červených obálek je mnoho, ale můžeme vytáhnout jen čtyřikrát, v obrovském moři tašek musíme najít ty nejcennější červené obálky a pak je nakreslit, zde jsou tři data pro referenci: hotovostní hodnota, hodnota dárku a počet příjemců, samozřejmě pokud je hotovost malá a počet lidí obdrží hodně lidí nebo hodnota ceny je extrémně vysoká (některé jsou dokonce šílené v jednotkách stovek milionů), Pak už to nestojí za to chytat, takže jsem dlouho váhal a nakonec jsem vymyslel algoritmus, jak měřit váhu červených obálek: hodnota červené obálky = hotovost / (počet příjemců + hodnota ceny).
Princip stránky žebříčku je stejný, najít klíčové tagy a pravidelně je párovat.
[mw_shl_code=java,true]def getTopList(url,daily,p):#排行榜红包 print u"--------- "+str(p)+"page---------" print "----------......----------" html=getData(url+'?daily='+str(daily)+'& p='+str(p)) pWrap=re.compile(r'<div class="list_info">(.+?) <span class="list_btn"></span>', re. DOTALL) #h Získejte list_info běžné pInfo=re.compile(r'.+<em class="num">(.+)</em>.+<em class="num">(.+)</em>.+<em class="num">(.+).</em>.+href="(.+)" class="btn rob_btn"',re. DOTALL) #获取红包信息 List=pWrap.findall(html,re. DOTALL) n=len(Seznam) pokud n==0: vraťte pro i v rozsahu(n): #Iterate přes všechny info_wrap div s=pInfo.match(Seznam) #取得红包信息 topinfo=list(s.groups(0))                info=list(topinfo) info[0]=topinfo[1].replace('\xd4\xaa','') #元->'' info[0]=float(info[0].replace('\xcd\xf2','0000')) #现金,10,>0000 info[1]=topinfo[2]. replace('\xd4\xaa','') #元->'' try: info[1]=float(info[1].replace('\xcd\xf2','0000')) #礼品价值 kromě výjimky, e:                        info[1]=float(info[1].replace('\xd2\xda','00000000')) #礼品价值 info[2]=topinfo[0].replace('\xb8\xf6',') #个->'' info[2]=float(info[2].replace('\xcd\xf2','0000')) #已发送                if info[2]==0: info[2]=1 #防止除数为0 if info[1]==0: info[1]=1 #防止除数为0 info.append(info[0]/(info[2]+info[1])) #红包价值, hotovost/(počet příjemců + hodnota dárku)                # pokud info[0]/(info[2]+info[1])>100: # vytisknout url luckyList.append(info) pokud 'class="page"' v html:#存在下一页 p=p+1                getTopList(url,daily,p) #递归调用自己爬取下一页[/mw_shl_code]Dobře, teď můžeme úspěšně procházet seznam dvou speciálních stránek a dalším krokem je získat seznam seznamů, tedy sbírku všech těchto adres, a pak je sbírat jednu po druhé:
[mw_shl_code=java,true]def getList(): print u"---------Find target---------" print "----------......----------" themeUrl={ #主题列表 'theme':'http://huodong.weibo.com/hongbao/theme',                 'pinpai':'http://huodong.weibo.com/hongbao/special_pinpai', 'daka':'http://huodong.weibo.com/hongbao/special_daka', 'youxuan':'http://huodong.weibo. com/hongbao/special_youxuan', 'qiye':'http://huodong.weibo.com/hongbao/special_qiye', 'quyu':'http://huodong.weibo.com/hongbao/special_quyu', 'meiti':'http: huodong.weibo.com/hongbao/special_meiti', 'hezuo':'http://huodong.weibo.com/hongbao/special_hezuo' } topUrl={ #排行榜列表 'mostmoney':'http://huodong.weibo. com/hongbao/top_mostmoney', 'mostsend':'http://huodong.weibo.com/hongbao/top_mostsend', 'mostsenddaka':'http://huodong.weibo.com/hongbao/top_mostsenddaka',                'mostsendpartner':'http://huodong.weibo.com/hongbao/top_mostsendpartner', 'cate':'http://huodong.weibo.com/hongbao/cate?type=', 'clothes':'http://huodong.weibo.com/ hongbao/cate?type=clothes', 'beauty':'http://huodong.weibo.com/hongbao/cate?type=beauty', 'fast':'http://huodong.weibo.com/hongbao/cate?type=fast', 'life':'http: huodong.weibo.com/hongbao/cate?type=life', 'digital':'http://huodong.weibo.com/hongbao/cate?type=digital', 'other':'http://huodong.weibo.com/hongbao/cate?type=other'                } pro (theme,url) v themeUrl.items(): tisknout "----------"+theme+"----------" tisknout URL vytisknout "----------......----------"                getThemeList(url,1) pro (top,url) v topUrl.items(): tisknout "----------"+top+"----------" tisknout URL vytisknout "----------......----------"                getTopList(url,0,1) getTopList(url,1,1)[/mw_shl_code]
 Pronajímatel| Zveřejněno 13.02.2015 22:47:13 |
0×05 Posuďte dostupnost červených obálek
Je to relativně jednoduché, nejdřív vyhledejte klíčová slova ve zdrojovém kódu, jestli je tam červené tlačítko pro zachycení obálky, a pak přejděte na umístění kolekce a zjistěte, jaký je nejvyšší rekord, pokud nejvíce dostane jen pár dolarů, tak sbohem......
Adresa pro zobrazení záznamu o inkasu je http://huodong.weibo.com/aj_hongbao/detailmore?page=1&type=2&_t=0&__rnd=1423744829265&uid=Red Envelope ID

[mw_shl_code=java,true]def checkValue(id): infoUrl='http://huodong.weibo.com/hongbao/'+str(id) html=getData(infoUrl) if 'action-type="lottery"' v html nebo True: #存在抢红包按钮                logUrl="http://huodong.weibo.com/aj_hongbao/detailmore?page=1&type=2&_t=0&__rnd=1423744829265&uid="+id #查看排行榜数据 param={} header= { 'Cache-Control': 'no-cache', 'Content-Type':'application/x-www-form-urlencoded', 'Pragma':'no-cache', 'Referer':'http://huodong.weibo.com/hongbao/detail? uid='+str(id), 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, podobně jako Gecko) Chrome/33.0.1750.146 BIDUBrowser/6.x Safari/537.36', 'X-Requested-With':'XMLHttpRequest' } res = postData(logUrl,param,header) pMoney=re.compile(r'<span class="money">(\d+?). +?) \xd4\xaa</span>', re. DOTALL) #h Get all list_info regulars luckyLog=pMoney.findall(html,re. DOTALL) pokud len(luckyLog)==0: maxMoney=0 jinak: maxMoney=float(luckyLog[0]) if maxMoney <nejnižší: #记录中最大红包小于设定值 return False else: print u"--------- ruka zpomaluje---------" print "----------......----------" return false        return True[/mw_shl_code]0×06 Dokončovací práce
Hlavní moduly jsou již na místě a nyní je potřeba všechny kroky propojit do série:
[mw_shl_code=java,true]def start(username,password,low,fromFile): gl=False lowest=low login(uživatelské jméno , heslo) if fromfile=='y': if os.path.exists('luckyList.txt'):                         try: f = file('luckyList.txt') newList = [] newList = p.load(f)                                print u'--------- load list---------' tisknout "----------......----------" kromě Exception, e: print u' nepodařilo se zpracovat lokální seznam, procházel online stránku. ' tisk "----------......----------" gl=Pravda jinak: tisk u' neexistuje lokálně luckyList.txt procházejících online stránek. ' print "----------......----------" gl=Pravda, pokud gl==Pravda: getList() z importu operátora itemgetter                newList=sorted(luckyList, key=itemgetter(4),reverse=True) f = file('luckyList.txt', 'w') p.dump(newList, f) #把抓到的列表存到文件里, takže příště nemusíte chytat f.close() pro štěstí newList: pokud ne 'http://huodong.weibo.com' v lucky[3]: #不是红包 pokračovat tisk lucky[3] id=re.findall(r'(\w*[0-9]+)\w*',lucky[3])                getLucky(id[0])[/mw_shl_code] Protože je velmi obtížné opakovaně procházet červený seznam obálek při každém testování, přidal jsem odstavec, který uloží celý seznam do kódu souboru, abyste si mohli přečíst lokální seznam a v budoucnu si červenou obálku přečíst.
[mw_shl_code=java,true]pokud __name__ == "__main__": print u"------------------ Weibo Red Envelope Assistant------------------" print "---------------------v0.0.1---------------------" print u"------------- od @***----------------" Tisk "-------------------------------------------------" try: uname=raw_input(u" Zadejte prosím svůj účet na Weibo: ".decode('utf-8').encode('gbk'))                pwd=raw_input(u"Zadejte prosím své heslo na Weibo: ".decode('utf-8').encode('gbk')) low=int(raw_input(u"Červená obálka pro přijetí maximální částky větší než n: ".decode('utf-8')).encode('gbk')))) fromfile=raw_input(u) Zda použít červený seznam obálek v luckyList.txt: (y/n) ".decode('utf-8').encode('gbk')) kromě výjimky, e: print u" parameter error" print "----------......----------" print e                exit(0) print u"--------- program start---------" print "----------......----------" start(uname,pwd, low, fromfile) print u" --------- program end--------- "print "----------...... ----------" os.system('pauza')[/mw_shl_code]
0×07 Jdeme!

0×07 Shrnutí
Základní kostra crawleru je v podstatě hotová, ve skutečnosti je stále hodně prostoru pro tento crawler v mnoha detailech, například úpravou pro podporu hromadného přihlášení, optimalizací algoritmu hodnoty červené obálky, samotný kód by měl mít také spoustu možností optimalizace, ale s mými schopnostmi odhaduji, že to zvládnu.
Nakonec všichni viděli výsledek programu, napsal jsem stovky řádků kódu, tisíce slov článků a všechno, na čem jsem tvrdě pracoval, byla sada dvoubarevných míčků, Nima pit dad, jak to může být dvoubarevný míček!! (Vypravěč: Čím víc autor mluvil, tím víc byl nadšený, a skutečně plakal, a lidé kolem něj ho přesvědčovali: Brácho, není to tak, není to jen červená obálka Weibo, včera mě bolely ruce a nevytřepal jsem červenou obálku z WeChatu.) )

Zveřejněno 14.02.2015 7:14:33 |
Kolik peněz jsi v Loulouu sebral?
Zveřejněno 02.03.2016 13:48:27 |
Vypadá tak vysoká
Zveřejněno 07.03.2016 12:51:02 |
Nevím, jestli je to vážné
Zřeknutí se:
Veškerý software, programovací materiály nebo články publikované organizací Code Farmer Network slouží pouze k učení a výzkumu; Výše uvedený obsah nesmí být používán pro komerční ani nelegální účely, jinak nesou všechny důsledky uživatelé. Informace na tomto webu pocházejí z internetu a spory o autorská práva s tímto webem nesouvisí. Musíte výše uvedený obsah ze svého počítače zcela smazat do 24 hodin od stažení. Pokud se vám program líbí, podporujte prosím originální software, kupte si registraci a získejte lepší skutečné služby. Pokud dojde k jakémukoli porušení, kontaktujte nás prosím e-mailem.

Mail To:help@itsvse.com