سبق Web Crawler کی تیاری

اس دھاگے میں ہم نے کسی بھی ویب پیج میں سے لنک کشید کرنے کے لیے کوڈ لکھنے کا آغاز کیا تھا۔

Strings کی مشقیں

اوپر دیے گئے دھاگے میں سے کوڈ کی ابتدا اور پھر بتدریج اس میں اضافوں کو تفصیل سے پڑھا جا سکتا ہے۔ آخر میں ہم کوڈ کی جس شکل تک پہنچ گئے تھے وہ مندرجہ ذیل ہے

PHP:
import urllib.request
 
def get_next_target(page):
    start_link = page.find('<a href=')      # start of link tag
    if start_link == -1:                    # if  link tage not found then return None and 0
        return None,0
    start_quote = page.find('"',start_link)  # index of first quote in link tag
    end_quote = page.find('"',start_quote+1) # index of second quote in link tag
    url = page[start_quote+1:end_quote]      # extracting string between start quote and end quote
 
    return url, end_quote                    # returing URL and the index of ending quote of link string
 
def get_all_links(page):
    links = []
    while True:
        url, endpos = get_next_target(page)  # calling function to get link and end position of lin i.e. second quote(")
        if url:                              # if url has some value(not empty hence true)
            links.append(url)                      # then append url in LINKS list
            page = page[endpos:]            # reassign page starting from the end of the found url and rest of the remaining page string
        else:
            break
    return links
 
#  opening a given url using URLLIB module
response = urllib.request.urlopen('http://www.urduweb.org')
 
# reading the file handle and converting it into a string using str() function
page = str(response.read())
 
# calling get_all_links function to further call get_next_target function and get a list of all links in a page
pagelist = get_all_links(page)
 
print(pagelist)
 
اب تک ہم نے ایک ایک ویب پیج کو seed پیج کے طور پر استعمال کیا ہے جس پر موجود لنکس کو ایک لسٹ میں محفوظ کیا۔
ایک لنک سے ہم مزید پیج تک پہنچ سکتے ہیں اور ان پر موجود لنکس کو بھی محفوظ کرنا اور اگلے لنکس تک پہنچنا ہمارا مقصد ہوگا۔

اس کام کو کرنے کے لیے ہمارے ویب کرالر کو تمام ویب پیج کا ٹریک رکھنا پڑے گا۔
اس کام کے لیے ہم tocrawl متغیر استعمال کریں گے جو ایک لسٹ ہوگی ایسے ویب پیج کی جن تک ابھی پہنچنا باقی ہوگا۔
جن ویب پیچ تک پہنچا جا چکا ہوگا انہیں ایک اور متغیر crawled میں رکھا جائے گا۔

اس کے کوڈ کا خاکہ کچھ اس طرح سے ہوگا

PHP:
start with tocrawl = [seed]
crawled = []
while there are more pages tocrawl:
    pick a page from tocrawl
    add that page to crawled
    add all the link targets on this page to tocrawl
return crawled
 
اب ایک فنکشن لکھیں جس کا نام ہو crawl_web اور اسے ایک سیڈ پیج seed page URL) URL) ان پٹ کے طور پر دیا جائے اور آؤٹ پٹ کے طور پر تمام URL کی لسٹ مہیا کر دے جن تک پہلے سیڈ پیج سے پہنچا جا سکتا ہے ۔
 

نمرہ

محفلین
ری یوزیبلٹی کا فائدہ اٹھاتے ہوئے:
PHP:
def crawl2(seed):
  ct=0
  crawled=[]
  tocr=[]
  tocr.append(seed)
  while tocr:
      ct=ct+1
      if ct==50:      #goes to infinity otherwise
          break
      crawled.append(tocr[0])
      print (tocr[0])
      import urllib.request
      try:
          response = urllib.request.urlopen(tocr[0])
          page = str(response.read())
          pagelist = get_all_links(page)
          tocr.extend(pagelist)
      except:
          print("an error here")
      del tocr[0]
  print(crawled)
  return crawled
 
ری یوزیبلٹی کا فائدہ اٹھاتے ہوئے:
PHP:
def crawl2(seed):
  ct=0
  crawled=[]
  tocr=[]
  tocr.append(seed)
  while tocr:
      ct=ct+1
      if ct==50:      #goes to infinity otherwise
          break
      crawled.append(tocr[0])
      print (tocr[0])
      import urllib.request
      try:
          response = urllib.request.urlopen(tocr[0])
          page = str(response.read())
          pagelist = get_all_links(page)
          tocr.extend(pagelist)
      except:
          print("an error here")
      del tocr[0]
  print(crawled)
  return crawled

کوڈ کام نہیں کر رہا نمرہ :)
میں نے سیڈ کے طور پر مندرجہ بالا لنک دیا

کوڈ:
crawl2('http://www.udacity.com/cs101x/index.html')

جواب میں یہ ایرر آ رہی ہے۔

کوڈ:
http://www.udacity.com/cs101x/index.html
an error here
['http://www.udacity.com/cs101x/index.html']
 
ری یوزیبلٹی کا فائدہ اٹھاتے ہوئے:
PHP:
def crawl2(seed):
  ct=0
  crawled=[]
  tocr=[]
  tocr.append(seed)
  while tocr:
      ct=ct+1
      if ct==50:      #goes to infinity otherwise
          break
      crawled.append(tocr[0])
      print (tocr[0])
      import urllib.request
      try:
          response = urllib.request.urlopen(tocr[0])
          page = str(response.read())
          pagelist = get_all_links(page)
          tocr.extend(pagelist)
      except:
          print("an error here")
      del tocr[0]
  print(crawled)
  return crawled


اب ذرا کوڈ کا تنقیدی جائزہ لے لیتے ہیں۔

ct=0

یہ اور اس کے بعد یہ دو لائنیں
PHP:
ct=ct+1
      if ct==50:      #goes to infinity otherwise
          break

یہ سب زائد کوڈ تھا اور شاید پچاس سے زائد ویب لنکس کو روکنے کے لیے لکھا گیا مگر ہم دیکھیں گے کہ اس کی ضرورت نہیں تھی اور یہ زائد کوڈ تھا جو شاید جانچ پڑتال کے دوران لکھا گیا اور ویسے ہی رہ گیا۔
 
کوڈ کے اس حصے کو ہم پہلے ایک فنکشن میں لکھ چکے ہیں اور اگر اب تک نہیں لکھا تو اب لازمی لکھ لینا چاہیے۔ :)

PHP:
  import urllib.request
      try:
          response = urllib.request.urlopen(tocr[0])
          page = str(response.read())
          pagelist = get_all_links(page)
          tocr.extend(pagelist)
      except:
          print("an error here")

اس کام کو ہم پہلے ایک فنکشن get_all_links میں لکھ چکے ہیں جسے ایک پیج پاس کیا جاتا ہے اور وہ تمام لنک ایک لسٹ کی شکل میں لوٹا دیتا ہے۔
پیج حاصل کرنے کے لیے کوڈ کو بھی ایک فنکشن میں لے جایا جانا چاہیے اب۔

PHP:
def get_page(url):
    try:
        import urllib
        return urllib.urlopen(url).read()
    except:
        return ""

PHP:
get_all_links(get_page(page)
 
کوڈ کی شکل کچھ یوں بنے گی ۔

PHP:
def crawl_web(seed):
    tocrawl = [seed]
    crawled = []
    while tocrawl:
        page = tocrawl.pop()
        if page not in crawled:
            pagelist = get_all_links(get_page(page))
            union(tocrawl,pagelist)
            crawled.append(page)
    return crawled
 
یونین کا فنکشن بھی لکھنا ہوگا جو کہ tocrawl لسٹ اور pagelist لسٹ کے مجموعہ پر مبنی ہوگا۔

PHP:
#p = tocrawl list & q = pagelist
def union(p,q):
    for e in q:
        if e not in p:
          p.append(e)
 

نمرہ

محفلین
کوڈ کام نہیں کر رہا نمرہ :)
میں نے سیڈ کے طور پر مندرجہ بالا لنک دیا

کوڈ:
crawl2('http://www.udacity.com/cs101x/index.html')

جواب میں یہ ایرر آ رہی ہے۔

کوڈ:
http://www.udacity.com/cs101x/index.html
an error here
['http://www.udacity.com/cs101x/index.html']
ویسے میرے پاس کام کر رہا ہے ابھی بھی:
PHP:
crawl2('http://www.udacity.com/cs101x/index.html')
آوٹ پٹ یہ ہے:
PHP:
http://www.udacity.com/cs101x/index.html
http://www.udacity.com/cs101x/crawling.html
http://www.udacity.com/cs101x/walking.html
http://www.udacity.com/cs101x/flying.html
http://www.udacity.com/cs101x/kicking.html
http://www.udacity.com/cs101x/index.html
http://www.udacity.com/cs101x/crawling.html
http://www.udacity.com/cs101x/walking.html
http://www.udacity.com/cs101x/flying.html
http://www.udacity.com/cs101x/kicking.html
 

نمرہ

محفلین
ایک سوال ہے ،اگر اسے وائل لوپ کے بجائے recursion سے کیا جائے تو کیا اس کی رفتار کم ہو جائے گی؟
 
یہ ضرور ہے کہ یہ کوڈ رکتا نہیں ہے، چلتا رہتا ہے۔

تو اس کوڈ میں یہ مسئلہ موجود ہے ورنہ لنکس کی تعداد اتنی زیادہ نہیں۔

بہرحال ، آپ کے کوڈ کی منطق 70 - 80 فیصد صحیح ہے جو کہ قابل تعریف ہے اور اس سے زیادہ قابل ستائش ہے کہ اب تک کی پائتھون کے دھاگوں پر واحد رکن ہیں جس نے تمام اسائنمنٹ پر کام کیا اور کوڈ پیش کیا جس پر اضافی نمبروں کی حقدار ہیں نمرہ :)

جو کوڈ بعد میں میں نے دیا ہے اسے چلا کر بھی نتائج کے مطلق بتائیں۔

باقی ممبران کہاں گم ہیں۔
محمد احمد
محمد صابر

تبصروں کے لیے دعوت ہے
ببلو
محمد سعد
 
ایک سوال ہے ،اگر اسے وائل لوپ کے بجائے recursion سے کیا جائے تو کیا اس کی رفتار کم ہو جائے گی؟

recursion پروگرامنگ زبانوں میں عموما اور پائتھون میں خصوصا پروگرام کی رفتار کو کم کر دیتی ہے۔

recursion فنکشن کال کی وجہ سے سست ہوتی ہے ، C میں تو فنکشن کال فقط JMP ہوتی ہے جبکہ پائتھون میں یہ نیم سپیس سکوپ سرچ (scope namespace search) , سٹیک سنبھالنا (stack handling) کی وجہ سے یہ بہت مہنگا آپریشن بن جاتی ہے اور اسے کرنے کی قیمت زیادہ ہونے کی وجہ سے الگورتھم کافی سست ہو جاتا ہے البتہ اسے بہتر کرنے کے کچھ طریقے ہیں جس میں ایک تکنیک memoization کی ہے جسے کئی زبانوں میں استعمال کیا جاتا ہے۔

اس لیے پائتھون میں جہاں بھی اعادہ(iteration) یا تکرار(recursion) کی ضرورت ہو وہاں لوپ (loop) بہتر رہتی ہے recursive functions کے مقابلے میں عمومی طور پر۔
stackless python کے بارے میں سنا ہے کہ اس میں یہ مسائل کم ہوتے ہیں مگر اس کے بارے میں تحقیق کی ضرورت ہے۔

سادہ recursion کی بجائے ایک طریقہ tail recursion کا ہے جس میں رفتار خاصی بڑھ جاتی ہے۔
اس موضوع پر میں ایک دھاگہ علیحدہ سے کھولتا ہوں وہاں اسے بہتر کرنے پر بھی تبادلہ خیال کرتے ہیں۔

ایک علیحدہ دھاگہ میں تعارف اور دو مثالوں سے وضاحت کی گئی ہے۔
Recursion
 
Top