unvisited strategy
This commit is contained in:
		
							parent
							
								
									3687403184
								
							
						
					
					
						commit
						75e1b0cd6d
					
				@ -40,9 +40,12 @@ class Response:
 | 
			
		||||
        self.redirects = redirects
 | 
			
		||||
        self.visited_time = datetime.date.today()
 | 
			
		||||
        self.bs = None
 | 
			
		||||
        self.link_status = link_status
 | 
			
		||||
        if content is not None and link_status == "good":
 | 
			
		||||
            self.bs = bs4.BeautifulSoup(content, "lxml")
 | 
			
		||||
            try:
 | 
			
		||||
                self.bs = bs4.BeautifulSoup(content, "lxml")
 | 
			
		||||
            except ValueError:
 | 
			
		||||
                link_status = "bad_parse"
 | 
			
		||||
        self.link_status = link_status
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return "{} {} {}".format(self.url,self.get_canonical(),self.link_status)
 | 
			
		||||
@ -374,7 +377,7 @@ def parse_and_index(work_link,parser,responses,db):
 | 
			
		||||
    if len(responses) > 0:
 | 
			
		||||
        db.index_responses(work_link,responses)
 | 
			
		||||
        lr = responses[-1]
 | 
			
		||||
        if lr.content is not None:
 | 
			
		||||
        if lr.bs is not None:
 | 
			
		||||
            target_link = lr.get_canonical()
 | 
			
		||||
            parsed = ParsedDocument(parser,target_link)
 | 
			
		||||
            parsed.extract(lr.content, lr.bs)
 | 
			
		||||
@ -384,11 +387,12 @@ def parse_and_index(work_link,parser,responses,db):
 | 
			
		||||
 | 
			
		||||
def visit_sitemap(domain,connection,parser,db):
 | 
			
		||||
    link = "http://" + domain
 | 
			
		||||
    print("Sitemap visit: " + link)
 | 
			
		||||
    responses = connection.html_download2(link)
 | 
			
		||||
    if len(responses) == 0:
 | 
			
		||||
        return False
 | 
			
		||||
    lr = responses[-1]
 | 
			
		||||
    if lr.link_status.startswith("bad_"):
 | 
			
		||||
    if lr.bs is None:
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    target_link,outlinks = parse_and_index(link,parser,responses,db)
 | 
			
		||||
@ -397,17 +401,18 @@ def visit_sitemap(domain,connection,parser,db):
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def visit_links(links,connection,parser,db):
 | 
			
		||||
def visit_links(links,connection,parser,db,is_online):
 | 
			
		||||
    # is is not online, then just check links
 | 
			
		||||
    outlinks = []
 | 
			
		||||
    junklinks = []
 | 
			
		||||
    badrobotlinks = []
 | 
			
		||||
    for work_link in links:
 | 
			
		||||
        responses = []
 | 
			
		||||
        if not parser.is_link_good(work_link):
 | 
			
		||||
            db.update_link_status(parser,work_link,"junk")
 | 
			
		||||
        elif connection.is_robot_good(work_link):
 | 
			
		||||
            db.update_link_status(parser,work_link,"bad_robot")
 | 
			
		||||
        else:
 | 
			
		||||
            db.update_link_status(work_link,"bad_link")
 | 
			
		||||
        elif is_online and not connection.is_robot_good(work_link):
 | 
			
		||||
            db.update_link_status(work_link,"bad_robot")
 | 
			
		||||
        elif is_online:
 | 
			
		||||
            responses = connection.html_download2(work_link)
 | 
			
		||||
            target_link,links = parse_and_index(work_link,parser,responses,db)
 | 
			
		||||
            nl = normalize_link(target_link)
 | 
			
		||||
@ -421,13 +426,14 @@ def visit_domain(domain,parser,db):
 | 
			
		||||
    p = parser
 | 
			
		||||
    # Get links from frontpage
 | 
			
		||||
    # TODO Sitemap
 | 
			
		||||
    res = visit_sitemap(domain,c,parser,db) 
 | 
			
		||||
    if not res:
 | 
			
		||||
        return False
 | 
			
		||||
    is_online = False
 | 
			
		||||
    if parser.is_domain_good(domain):
 | 
			
		||||
        # Is domain online?
 | 
			
		||||
        is_online = visit_sitemap(domain,c,parser,db) 
 | 
			
		||||
    for i in range(p.crawl_rounds):
 | 
			
		||||
        # Visit links from frontpage
 | 
			
		||||
        links = db.get_visit_links(domain,p.recent_links,p.old_links,p.random_links)
 | 
			
		||||
        visit_links(links,c,p,db)
 | 
			
		||||
        visit_links(links,c,p,db,is_online)
 | 
			
		||||
        db.check_domain(domain)
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,8 @@ import os
 | 
			
		||||
import pkg_resources
 | 
			
		||||
import datetime
 | 
			
		||||
from websucker.parser import normalize_link,urlunparse
 | 
			
		||||
import collections
 | 
			
		||||
import math
 | 
			
		||||
 | 
			
		||||
VERSION = "sucker6"
 | 
			
		||||
 | 
			
		||||
@ -140,14 +142,16 @@ INSERT INTO content(
 | 
			
		||||
    def index_responses(self,source_link,responses):
 | 
			
		||||
        # Redirect links
 | 
			
		||||
        pl = normalize_link(source_link)
 | 
			
		||||
        domain = pl[1]
 | 
			
		||||
        npl = urlunparse(pl)
 | 
			
		||||
        for response in responses:
 | 
			
		||||
            tl = response.get_canonical()
 | 
			
		||||
            if pl != tl:
 | 
			
		||||
                self.update_link_status(source_link,"redirect",tl)
 | 
			
		||||
            if npl != tl:
 | 
			
		||||
                self.update_link_status(npl,"redirect",tl)
 | 
			
		||||
            d = (
 | 
			
		||||
                pl[1],
 | 
			
		||||
                source_link,
 | 
			
		||||
                response.get_canonical(),
 | 
			
		||||
                domain,
 | 
			
		||||
                npl,
 | 
			
		||||
                tl,
 | 
			
		||||
                response.redirects,
 | 
			
		||||
                response.status,
 | 
			
		||||
                response.headers,
 | 
			
		||||
@ -166,8 +170,16 @@ INSERT INTO content(
 | 
			
		||||
        fd = 0
 | 
			
		||||
        jd = 0
 | 
			
		||||
        rows = self.session.execute("SELECT domain_name,good_size,content_size, fetched_count,seen_count FROM domain_quality PER PARTITION LIMIT 1")
 | 
			
		||||
        # TODO submdomain analysis
 | 
			
		||||
        #dd = collections.defaultdict(set)
 | 
			
		||||
        for row in rows:
 | 
			
		||||
            if not parser.is_domain_good(row[0]):
 | 
			
		||||
            domain = row[0]
 | 
			
		||||
            #subdomains = domain.split(".")
 | 
			
		||||
            #d2 = subdomains[-2] + "." + subdomains[-1]
 | 
			
		||||
            #if len(subdomains) > 2:
 | 
			
		||||
            #    d3 = ".".join(subdomains[0:-2])
 | 
			
		||||
            #    dd[d2].add(d3)
 | 
			
		||||
            if not parser.is_domain_good(domain):
 | 
			
		||||
                jd += 1
 | 
			
		||||
            if row[1] is not None:
 | 
			
		||||
                gs += row[1]
 | 
			
		||||
@ -191,6 +203,9 @@ INSERT INTO content(
 | 
			
		||||
        print("Junk domains: {}".format(jd))
 | 
			
		||||
        print("New links : {}".format(sl))
 | 
			
		||||
        print("Finished domains : {}".format(fd))
 | 
			
		||||
        #for d,sd in dd.items():
 | 
			
		||||
        #    if len(sd) > 1:
 | 
			
		||||
        #        print(d + " " +  ",".join(sd))
 | 
			
		||||
 | 
			
		||||
    def daily_report(self):
 | 
			
		||||
        #rows = self.session.execute(self.daily_links_select)
 | 
			
		||||
@ -222,8 +237,8 @@ INSERT INTO content(
 | 
			
		||||
                
 | 
			
		||||
        print("{} domains, {} documents, {} characters ".format(len(domains),total_count,total_size))
 | 
			
		||||
 | 
			
		||||
    def update_link_status(self,parser,links,status,redirect_target=None):
 | 
			
		||||
        pl = normalize_link(source_link)
 | 
			
		||||
    def update_link_status(self,link,status,redirect_target=None):
 | 
			
		||||
        pl = normalize_link(link)
 | 
			
		||||
        r = (
 | 
			
		||||
            status,
 | 
			
		||||
            redirect_target,
 | 
			
		||||
@ -244,6 +259,7 @@ INSERT INTO content(
 | 
			
		||||
                follow_links.add(urlunparse(link))
 | 
			
		||||
 | 
			
		||||
        newlinkdomains = set()
 | 
			
		||||
        newlinkcount = 0
 | 
			
		||||
        for link in follow_links:
 | 
			
		||||
            value = []
 | 
			
		||||
            nl = normalize_link(link)
 | 
			
		||||
@ -253,8 +269,10 @@ INSERT INTO content(
 | 
			
		||||
            row = rows.one()
 | 
			
		||||
            if row.applied:
 | 
			
		||||
                newlinkdomains.add(nl[1])
 | 
			
		||||
                newlinkcount += 1
 | 
			
		||||
        for domain in newlinkdomains:
 | 
			
		||||
            self.check_domain(domain)
 | 
			
		||||
        print("{} new links, {} new domains".format(newlinkcount,len(newlinkdomains)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def index_content(self,target_link,parsed_document):
 | 
			
		||||
@ -306,7 +324,6 @@ INSERT INTO content(
 | 
			
		||||
            originality = self.check_document(pd.paragraph_checksums,pd.paragraph_sizes)
 | 
			
		||||
            if originality < 0.8:
 | 
			
		||||
                link_status = "bad_copy"
 | 
			
		||||
        print(nl)
 | 
			
		||||
        self.session.execute(self.index_content_links_update,(link_status,originality,tsz,nl[0],nl[1],nl[2],nl[3]))
 | 
			
		||||
        content_future.result()
 | 
			
		||||
        print("<<<< " + link_status + " " + str(originality))
 | 
			
		||||
@ -428,7 +445,6 @@ INSERT INTO content(
 | 
			
		||||
        domain)
 | 
			
		||||
        if fetched_count > 0 or seen_count > 0:
 | 
			
		||||
            self.session.execute(self.domain_quality_update,uv)
 | 
			
		||||
        print(uv)
 | 
			
		||||
        return average_fetched_good_characters
 | 
			
		||||
 | 
			
		||||
    def all_domains(self,count):
 | 
			
		||||
@ -476,16 +492,34 @@ INSERT INTO content(
 | 
			
		||||
        # get all domains
 | 
			
		||||
        rows = self.session.execute(self.domains_select)
 | 
			
		||||
        domains = []
 | 
			
		||||
        # Analyze third level domains
 | 
			
		||||
        dd = collections.defaultdict(set)
 | 
			
		||||
        third_count = 0
 | 
			
		||||
        for row in rows:
 | 
			
		||||
            domain = row[0]
 | 
			
		||||
            seen_count = row[1]
 | 
			
		||||
            fetched_count = row[2]
 | 
			
		||||
            gain_ratio = row[3]
 | 
			
		||||
            afg = row[4]
 | 
			
		||||
            if seen_count and not fetched_count and parser.is_domain_good(domain):
 | 
			
		||||
                domains.append((domain,0))
 | 
			
		||||
        ss = min(len(domains),count)
 | 
			
		||||
        return random.sample(domains,ss)
 | 
			
		||||
            if seen_count and not fetched_count:
 | 
			
		||||
                subdomains = domain.split(".")
 | 
			
		||||
                d2 = subdomains[-2] + "." + subdomains[-1]
 | 
			
		||||
                dd[d2].add(domain)
 | 
			
		||||
        # Select second level first
 | 
			
		||||
        result = []
 | 
			
		||||
        # then select third level
 | 
			
		||||
        ll = list(dd.items()) 
 | 
			
		||||
        random.shuffle(ll)
 | 
			
		||||
        domain_weight = count / len(ll) 
 | 
			
		||||
        for domain,subdomains in ll:
 | 
			
		||||
            dl = list(subdomains)
 | 
			
		||||
            link_weight = domain_weight / len(dl)
 | 
			
		||||
            random.shuffle(dl)
 | 
			
		||||
            for d in dl:
 | 
			
		||||
                r = random.random()
 | 
			
		||||
                if r < link_weight:
 | 
			
		||||
                    result.append((d,0))
 | 
			
		||||
        return result
 | 
			
		||||
    
 | 
			
		||||
    def get_visit_links(self,domain,recent_count,old_count,random_count):
 | 
			
		||||
        dblinks = []
 | 
			
		||||
 | 
			
		||||
@ -113,7 +113,7 @@ class BaseParser:
 | 
			
		||||
            r = "Port in domain"
 | 
			
		||||
        elif len(domain) < 4:
 | 
			
		||||
            r = "Too short domain"
 | 
			
		||||
        elif len(domain) > 50:
 | 
			
		||||
        elif len(domain) > 127:
 | 
			
		||||
            r = "Too long location"
 | 
			
		||||
        elif domain.startswith(".") or domain.endswith("."):
 | 
			
		||||
            r = "Malformed domain"
 | 
			
		||||
@ -152,16 +152,8 @@ class BaseParser:
 | 
			
		||||
                return False
 | 
			
		||||
            for c in link:
 | 
			
		||||
                if ord(c) >= 128:
 | 
			
		||||
                    r = "Bad domain character"
 | 
			
		||||
                    r = "Bad link character"
 | 
			
		||||
                    break
 | 
			
		||||
            for p in self.skipdomains:
 | 
			
		||||
                if domain.endswith(p):
 | 
			
		||||
                    r = "Bad domain"
 | 
			
		||||
                    break
 | 
			
		||||
            if ".b-" in domain:
 | 
			
		||||
                r = "Bad domain"
 | 
			
		||||
            if len(domain) > 127:
 | 
			
		||||
                r = "Too long path"
 | 
			
		||||
            # Path
 | 
			
		||||
            for t in self.skiptypes:
 | 
			
		||||
                if path.lower().endswith(t):
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user