рдкрдХрдбрд╝реЛ - рдкрд╛рд░реНрд╕рд┐рдВрдЧ рд╕рд╛рдЗрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдЬрдЧрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп

рд▓рдЧрднрдЧ рдкрд╛рдБрдЪ рдпрд╛ рдЫрд╣ рд╕рд╛рд▓ рдкрд╣рд▓реЗ, рдЬрдм рдореИрдВ рдЕрднреА рднреА рдкреАрдПрдЪрдкреА рдореЗрдВ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд░ рд░рд╣рд╛ рдерд╛, рддреЛ рдореИрдВрдиреЗ рд╕рд╛рдЗрдЯреНрд╕ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реНрд▓ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рдореБрдЭреЗ рдПрдХ рдЙрдкрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА рдЬрд┐рд╕рдиреЗ рдореБрдЭреЗ рдХрд┐рд╕реА рд╕рд╛рдЗрдЯ рдкрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рддреНрд░ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ, рдПрдХ рдирд┐рдпрдорд┐рдд рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд╣реЗрдбрд░ рднреЗрдЬрдиреЗ рдФрд░ POST рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдХрд╛ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреАред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдореИрдВрдиреЗ рд╕реАрдзреЗ рдХрд░реНрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрд╣реБрдд рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдерд╛ рдФрд░ рдореИрдВрдиреЗ рдПрдХ рд╕рд░рд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рдЖрд╡рд░рдг рд▓рд┐рдЦрд╛ред рд╕рдордп рдмреАрддрддрд╛ рдЧрдпрд╛, рдореИрдВ рдЕрдЬрдЧрд░ рдХреЗ рдкрд╛рд╕ рдЧрдпрд╛ рдФрд░ рдЙрд╕реА рдУрдХ рдХрд░реНрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдПрдкреАрдЖрдИ рдореЗрдВ рднрд╛рдЧ рдЧрдпрд╛ред рдореБрдЭреЗ рдЕрдЬрдЧрд░ рдореЗрдВ рд░реИрдкрд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рдкрдбрд╝рд╛ред

рд╣рдбрд╝рдкрдирд╛ рдХреНрдпрд╛ рд╣реИ?


рдпрд╣ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рд╕рд╛рдЗрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИред рдЗрд╕рдХреЗ рдореБрдЦреНрдп рдХрд╛рд░реНрдп:


рдЕрдЧрд▓рд╛, рдореИрдВ рдкреНрд░рддреНрдпреЗрдХ рдЖрдЗрдЯрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рдХрд╛рд░реНрдп рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЖрд░рдореНрдн рдХрд░рдиреЗ рдФрд░ рдПрдХ рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдз рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВред рдореИрдВ рдХреЛрдб рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛ рдЬреЛ рдпрд╛рдВрдбреЗрдХреНрд╕ рд╕реЗ рдПрдХ рдкреГрд╖реНрда рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рд╣реЗрдЬрддрд╛ рд╣реИ:
>>> g = Grab(log_file='out.html') >>> g.go('http://yandex.ru') 

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, `log_file` рдкреИрд░рд╛рдореАрдЯрд░ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рд╣реИ - рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрдЧреЗ рдХреЗ рдЕрдзреНрдпрдпрди рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдирд┐рдХрд╛рдп рдХреЛ рдХрд╣рд╛рдБ рд╕рд╣реЗрдЬрдирд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЖрдк рдЗрд╕реЗ рдлрд╝рд╛рдЗрд▓ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╣рдордиреЗ рджреЗрдЦрд╛ рдХрд┐ рдЖрдк рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдЧреНрд░реИрдм рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдХреИрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рд╕рд╣реАред рдФрд░ рдпрд╣рд╛рдБ рдПрдХ рд╣реА рдХреЛрдб рдХреЗ рдХреБрдЫ рдФрд░ рд╕рдВрд╕реНрдХрд░рдг рд╣реИрдВ:
 >>> g = grab() >>> g.setup(url='http://yandex.ru', log_file='out.html') >>> g.request() 

рдпрд╛
 >>> g = Grab() >>> g.go('http://yandex.ru', log_file='out.html') 


рд╕рдмрд╕реЗ рдЫреЛрдЯрд╛:
 >>> Grab(log_file='out.html').go('http://yandex.ru') 


рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ: рдЖрдк рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, 'рд╕реЗрдЯрдЕрдк' рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдпрд╛ `рдЧреЛ 'рдФрд░` рдЕрдиреБрд░реЛрдз` рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рдбрд╝рдкрдиреЗ рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред `Go` рдкрджреНрдзрддрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЕрдиреБрд░реЛрдзрд┐рдд URL рдХреЛ рдПрдХ рд╕реНрдереИрддрд┐рдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЕрдиреНрдп рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЗрд╕реЗ рдПрдХ рдирд╛рдорд┐рдд рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред `Go` рдФрд░` request` рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ `go` рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрдмрдХрд┐ рдЕрдиреБрд░реЛрдз рдХреЛ рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ рдФрд░ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗрдЯ рдХрд┐рдП рдЧрдП URL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

`Log_file` рд╡рд┐рдХрд▓реНрдк рдХреЗ рдЕрд▓рд╛рд╡рд╛,` log_dir` рд╡рд┐рдХрд▓реНрдк рд╣реИ, рдЬреЛ рдмрд╣реБ-рдХрджрдо рдкрд╛рд░реНрд╕рд░ рдХреЛ рдбреАрдмрдЧ рдХрд░рдирд╛ рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред
 >>> import logging >>> from grab import Grab >>> logging.basicConfig(level=logging.DEBUG) >>> g = Grab() >>> g.setup(log_dir='log/grab') >>> g.go('http://yandex.ru') DEBUG:grab:[02] GET http://yandex.ru >>> g.setup(post={'hi': u', !'}) >>> g.request() DEBUG:grab:[03] POST http://yandex.ru 


рдЖрдк рджреЗрдЦрддреЗ рд╣реИрдВ? рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЛ рдПрдХ рдирдВрдмрд░ рдорд┐рд▓рд╛ред рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдлрд╝рд╛рдЗрд▓ / tmp / [рд╕рдВрдЦреНрдпрд╛ 022.html рдореЗрдВ рджрд░реНрдЬ рдХреА рдЧрдИ рдереА, рдФрд░ / tmp / [рд╕рдВрдЦреНрдпрд╛ 022.log рдлрд╝рд╛рдЗрд▓ рднреА рдмрдирд╛рдИ рдЧрдИ рдереА, рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ http-headers рджрд░реНрдЬ рдХрд┐рдП рдЧрдП рдереЗред рдФрд░ рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ? рд╡рд╣ рдпреИрдВрдбреЗрдХреНрд╕ рдХреЗ рдореБрдЦреНрдп рдкреГрд╖реНрда рдкрд░ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдлрд┐рд░ рдпрд╣ рдЙрд╕реА рдкреГрд╖реНрда рдкрд░ рдПрдХ рд╡реНрдпрд░реНрде POST рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИред рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рджреВрд╕рд░реЗ рдЕрдиреБрд░реЛрдз рдореЗрдВ рд╣рдо URL рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ - рдкрд┐рдЫрд▓реЗ рдЕрдиреБрд░реЛрдз рдХрд╛ url рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЖрдЗрдП рдПрдХ рдФрд░ рдкрдХрдбрд╝реЛ рдбрд┐рдмрдЧрд┐рдВрдЧ рд╕реЗрдЯрд┐рдВрдЧ рдХреЛ рджреЗрдЦреЗрдВред
 >>> g = Grab() >>> g.setup(debug=True) >>> g.go('http://youporn.com') >>> g.request_headers {'Accept-Language': 'en-us;q=0.9,en,ru;q=0.3', 'Accept-Encoding': 'gzip', 'Keep-Alive': '300', 'Accept': 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.3', 'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.9.0.2) Gecko/2008091620 Firefox/3.0.2', 'Accept-Charset': 'utf-8,windows-1251;q=0.7,*;q=0.7', 'Host': 'www.youporn.com'} 


рд╣рдордиреЗ youporn.com рд╕реЗ рдПрдХ рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ред рдбрд┐рдмрдЧ рд╡рд┐рдХрд▓реНрдк рдЖрдЙрдЯрдЧреЛрдЗрдВрдЧ рдЕрдиреБрд░реЛрдз рд╣реЗрдбрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИред рдпрджрд┐ рд╣рдо рдХреБрдЫ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдордиреЗ рд╕рд░реНрд╡рд░ рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рднреЗрдЬрд╛ рд╣реИред Request_headers рд╡рд┐рд╢реЗрд╖рддрд╛ рдореЗрдВ рдЕрдиреБрд░реЛрдз рдХреЗ http рд╣реЗрдбрд░ рдХреА рдХреБрдВрдЬрд┐рдпреЛрдВ рдФрд░ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рд╣реИред

рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд╕рдВрдХрд▓рди рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рдХреНрд╖рдорддрд╛рдУрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

Http рдЕрдиреБрд░реЛрдз рд╡рд┐рдзрд┐рдпреЛрдВ


рдкреЛрд╕реНрдЯ рдЕрдиреБрд░реЛрдзред рдпрд╣ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред `рдкреЛрд╕реНрдЯ` рд╡рд┐рдХрд▓реНрдк рдореЗрдВ рдХреБрдВрдЬрд┐рдпреЛрдВ рдФрд░ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВред рдкрдХрдбрд╝реЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЕрдиреБрд░реЛрдз рдкреНрд░рдХрд╛рд░ рдХреЛ POST рдореЗрдВ рдмрджрд▓ рджреЗрдЧрд╛ред
 >>> g = Grab() >>> g.setup(post={'act': 'login', 'redirec_url': '', 'captcha': '', 'login': 'root', 'password': '123'}) >>> g.go('http://habrahabr.ru/ajax/auth/') >>> print g.xpath_text('//error')    


рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рдпрджрд┐ рдХреЛрдИ POST рдбреЗрдЯрд╛ рдпрд╛ рдЕрдиреБрд░реЛрдз рд╡рд┐рдзрд┐ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реЗрдЯ рдирд╣реАрдВ рдХреА рдЧрдИ рд╣реИ, рддреЛ Grab рдПрдХ GET рдЕрдиреБрд░реЛрдз рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ред

PUT, DELETE, HEAD рд╡рд┐рдзрд┐рдпрд╛рдБред рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд░реВрдк рд╕реЗ, рдпрджрд┐ рдЖрдк рд╡рд┐рдХрд▓реНрдк рд╡рд┐рдзрд┐ = 'рдбрд┐рд▓реАрдЯ', рд╡рд┐рдзрд┐ = 'рдкреБрдЯ' рдпрд╛ рд╡рд┐рдзрд┐ = 'рд╣реЗрдб' рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдореИрдВрдиреЗ рдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдмрд╣реБрдд рдХрдо рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдЙрдирдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВред

POST рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕реВрдЪрдирд╛ред рдкрдХрдбрд╝реЛ рдХреЛ рджрд┐рдП рдЧрдП рд╕рднреА рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рдмрдЪрд╛рдиреЗ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рд╢реНрдиреЛрдВ рдореЗрдВ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдПрдХрдорд╛рддреНрд░ рд╡рд┐рдХрд▓реНрдк рдЬреЛ рдЗрд╕реЗ рдирд╣реАрдВ рдмрдЪрд╛рддрд╛ рд╣реИ рд╡рд╣ `рдкреЛрд╕реНрдЯ` рд╡рд┐рдХрд▓реНрдк рд╣реИред рдпрджрд┐ рдЙрд╕рдиреЗ рдЗрд╕реЗ рд╕рд╣реЗрдЬрд╛ рд╣реИ, рддреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдЖрдк рджреВрд╕рд░реЗ URL рдкрд░ рдПрдХ POST рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдВрдЧреЗ, рдФрд░ рдпрд╣ рд╢рд╛рдпрдж рд╣реА рдЖрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВ:
 >>> g.setup(post={'login': 'root', 'password': '123'}) >>> g.go('http://example.com/login') >>> g.go('http://example.com/news/recent') 


HTTP рд╢реАрд░реНрд╖ рд▓реЗрдЦ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ


рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рднреЗрдЬреЗ рдЧрдП рд╣реЗрдбрд░ рдХреЛ рдХреИрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣реЗрдбрд░ рд╢рдмреНрджрдХреЛрд╢ рдХреЛ 'рд╣реЗрдбрд░' рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде рд╕реЗрдЯ рдХрд░реЗрдВред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдЧреНрд░реИрдм рдХреБрдЫ рд╣реЗрдбрд░ рдХреЛ рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреА рддрд░рд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ: рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдВ, рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдВ-рднрд╛рд╖рд╛, рд╕реНрд╡реАрдХрд╛рд░-рд╕рд╛рд░рдереА, рдХреАрдк-рдЕрд▓рд╛рдЗрд╡ред рдЖрдк рдЙрдиреНрд╣реЗрдВ 'рд╣реЗрдбрд░' рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде рднреА рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ:
 >>> g = Grab() >>> g.setup(headers={'Accept-Encoding': ''}) >>> g.go('http://digg.com') >>> print g.response.headers.get('Content-Encoding') None >>> g.setup(headers={'Accept-Encoding': 'gzip'}) >>> g.go('http://digg.com') >>> print g.response.headers['Content-Encoding'] gzip 


рдХреБрдХреАрдЬрд╝ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ


рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдЧреНрд░реИрдм рдкреНрд░рд╛рдкреНрдд рдХреБрдХреАрдЬрд╝ рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЕрдЧрд▓реЗ рдЕрдиреБрд░реЛрдз рдореЗрдВ рднреЗрдЬрддрд╛ рд╣реИред рдЖрдкрдХреЛ рдмреЙрдХреНрд╕ рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рддреНрд░ рдЕрдиреБрдХрд░рдг рдорд┐рд▓рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ `reuse_cookies` рд╡рд┐рдХрд▓реНрдк рдХреЛ рдЕрдХреНрд╖рдо рдХрд░реЗрдВред рдЖрдк рдХреБрдХреАрдЬрд╝ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ `рдХреБрдХреАрдЬрд╝` рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рдореЗрдВ рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд┐рд╕рдХрд╛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг` рдкреЛрд╕реНрдЯ` рд╡рд┐рдХрд▓реНрдк рдореЗрдВ рдкреНрд░реЗрд╖рд┐рдд рдбреЗрдЯрд╛ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рдорд╛рди рд╣реИред
 >>> g.setup(cookies={'secureid': '234287a68s7df8asd6f'}) 


рдЖрдк рдЙрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреБрдХреА 'рд╡рд┐рдХрд▓реНрдк' рдХреЗ рд╕рд╛рде рдХреБрдХреА рднрдВрдбрд╛рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдЖрдкрдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЙрдиреНрдЪ рдХреЗ рдмреАрдЪ рдХреБрдХреАрдЬрд╝ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред

рдХрд┐рд╕реА рднреА рд╕рдордп, рдЖрдк рдбрдВрдк_рдХреВрдХ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЧреНрд░реИрдм рдСрдмреНрдЬреЗрдХреНрдЯ рдХреБрдХреАрдЬрд╝ рдХреЛ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдлрд╛рдЗрд▓ рд╕реЗ рд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ load_cookies рд╡рд┐рдзрд┐ред рдкрдХрдбрд╝реЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рдХреБрдХреАрдЬрд╝ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, 'clear_cookies` рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдЬреЗрдВрдЯ


рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдЧреНрд░реИрдм рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╣реЛрдиреЗ рдХрд╛ рджрд┐рдЦрд╛рд╡рд╛ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдПрдЬреЗрдВрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдХ рдЧреНрд░реИрдм рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╕рдордп рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд░реВрдк рд╕реЗ рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдмреЗрд╢рдХ, рдЖрдк рдЕрдкрдиреЗ рдпреВрдЬрд░-рдПрдЬреЗрдВрдЯ рдХреЛ `user_agent` рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
 >>> from grab import Grab >>> g = Grab() >>> g.go('http://whatsmyuseragent.com/') >>> g.xpath('//td[contains(./h3/text(), "Your User Agent")]').text_content() 'The Elements of Your User Agent String Are:\nMozilla/5.0\r\nWindows\r\nU\r\nWindows\r\nNT\r\n5.1\r\nen\r\nrv\r\n1.9.0.1\r\nGecko/2008070208\r\nFirefox/3.0.1' >>> g.setup(user_agent='Porn-Parser') >>> g.go('http://whatsmyuseragent.com/') >>> g.xpath('//td[contains(./h3/text(), "Your User Agent")]').text_content() 'The Elements of Your User Agent String Are:\nPorn-Parser' 


рдкреНрд░реЙрдХреНрд╕реА рд╕рд░реНрд╡рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ


рд╕рдм рдХреБрдЫ рдЯреНрд░рд╛рдЗрдЯ рд╣реИред рдкреНрд░реЙрдХреНрд╕реА рд╡рд┐рдХрд▓реНрдк рдореЗрдВ, рдЖрдкрдХреЛ "рд╕рд░реНрд╡рд░: рдкреЛрд░реНрдЯ" рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░реЙрдХреНрд╕реА рдкрддреЗ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдкреНрд░реЙрдХреНрд╕реА_рдЯрд╛рдЗрдк рд╡рд┐рдХрд▓реНрдк рдореЗрдВ рд╣рдо рдЗрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ: http, рдореЛрдЬреЗ 4 рдпрд╛ рдореЛрдЬрд╝реЗ 5 рдпрджрд┐ рдЖрдкрдХреЗ рдкреНрд░реЙрдХреНрд╕реА рдХреЛ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдкреНрд░реЙрдХреНрд╕реА_рд╕реБрдореЗрд░ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдорд╛рди рдЬрд┐рд╕рдХреЗ рдкрд╛рд╕ "рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛: рдкрд╛рд╕рд╡рд░реНрдб" рд╣реИред
Google рдЦреЛрдЬ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╕рдмрд╕реЗ рд╕рд░рд▓ рдкреНрд░реЙрдХреНрд╕реА рдЦреЛрдЬ рдЗрдВрдЬрди:
 >>> from grab import Grab, GrabError >>> from urllib import quote >>> import re >>> g = Grab() >>> g.go('http://www.google.ru/search?num=100&q=' + quote('free proxy +":8080"')) >>> rex = re.compile(r'(?:(?:[-a-z0-9]+\.)+)[a-z0-9]+:\d{2,4}') >>> for proxy in rex.findall(g.drop_space(g.css_text('body'))): ... g.setup(proxy=proxy, proxy_type='http', connect_timeout=5, timeout=5) ... try: ... g.go('http://google.com') ... except GrabError: ... print proxy, 'FAIL' ... else: ... print proxy, 'OK' ... 210.158.6.201:8080 FAIL ... proxy2.com:80 OK тАж. 210.107.100.251:8080 OK тАж. 


рдЙрддреНрддрд░ рдХрд╛рд░реНрдп


рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдкрдиреЗ рдЧреНрд░реИрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рд╣реИред рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реИ? `Go` рдФрд░` request` рд╡рд┐рдзрд┐рдпрд╛рдБ рдПрдХ рд░рд┐рд╕реНрдкрд╛рдВрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реМрдЯрд╛рдПрдВрдЧреЗ, рдЬреЛ рдЧреНрд░реИрдм рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА `рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛` рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднреА рдЙрдкрд▓рдмреНрдз рд╣реИред рдЖрдк рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╡рд╕реНрддреБ рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЧреБрдгреЛрдВ рдФрд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ: рдХреЛрдб, рдмреЙрдбреА, рд╣реЗрдбрд░, рдпреВрдЖрд░рдПрд▓, рдХреБрдХреАрдЬ, рдЪрд╛рд░рд╕реЗрдЯред


рдЧреНрд░реИрдм рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ `response_unicode_body` рдирд╛рдордХ рдПрдХ рд╡рд┐рдзрд┐ рд╣реИ, рдЬреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдмреЙрдбреА рдХреЛ рдпреВрдирд┐рдХреЛрдб рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рджреЗрддрд╛ рд╣реИ, рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ HTML рдкреНрд░рдХрд╛рд░ рдХреА рдЗрдХрд╛рдЗрдпрд╛рдБ рдФрд░ рдпреВрдирд┐рдХреЛрдб рд╕рдордХрдХреНрд╖реЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВред

рдЕрдВрддрд┐рдо рдЕрдиреБрд░реЛрдз рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣рдореЗрд╢рд╛ рд╡рд┐рд╢реЗрд╖рддрд╛ `рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛` рдкрдХрдбрд╝реЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛрддреА рд╣реИред
 >>> g = Grab() >>> g.go('http://aport.ru') >>> g.response.code 200 >>> g.response.cookies {'aportuid': 'AAAAGU5gdfAAABRJAwMFAg=='} >>> g.response.headers['Set-Cookie'] 'aportuid=AAAAGU5gdfAAABRJAwMFAg==; path=/; domain=.aport.ru; expires=Wed, 01-Sep-21 18:21:36 GMT' >>> g.response.charset 'windows-1251' 


рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкрд╛рда рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдп рдХрд░рдирд╛ (Grab.ext.text рдПрдХреНрд╕рдЯреЗрдВрд╢рди)


рдЦреЛрдЬ рд╡рд┐рдзрд┐ рдЖрдкрдХреЛ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ рдХрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдирд┐рдХрд╛рдп рдореЗрдВ рдореМрдЬреВрдж рд╣реИ рдпрд╛ рдирд╣реАрдВ, рдЦреЛрдЬ_рд╕рдВрдмрдВрдз рд╡рд┐рдзрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреА рд╣реИред рдпрджрд┐ рддрд░реНрдХ рдирд╣реАрдВ рдорд┐рд▓рд╛, рддреЛ Assert_substring рдФрд░ assert_rex рддрд░реАрдХреЗ DataNotFound рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХ рджреЗрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЗрд╕ рд╡рд┐рд╕реНрддрд╛рд░ рдореЗрдВ рдРрд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХрд╛рд░реНрдп рд╣реИрдВ рдЬреИрд╕реЗ `find_number - рдкрд╣рд▓реА рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдШрдЯрдирд╛ рдХреА рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ,` drop_space` - рдХрд┐рд╕реА рднреА рд╡реНрд╣рд╛рдЯреНрд╕рдПрдк рд╡рд░реНрдг рдХреЛ рд╣рдЯрд╛рддрд╛ рд╣реИ рдФрд░ `normalize_space` - рдПрдХ рд╕реНрдерд╛рди рдХреЗ рд╕рд╛рде рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рдХреЗ рдХреНрд░рдо рдХреЛ рдмрджрд▓рддрд╛ рд╣реИред
 >>> g = Grab() >>> g.go('http://habrahabr.ru') >>> g.search(u'Google') True >>> g.search(u'') False >>> g.search(u'') False >>> g.search(u'') False >>> g.search(u'') True >>> g.search('') Traceback (most recent call last): File "", line 1, in File "grab/ext/text.py", line 37, in search raise GrabMisuseError('The anchor should be byte string in non-byte mode') grab.grab.GrabMisuseError: The anchor should be byte string in non-byte mode >>> g.search('', byte=True) True >>> import re >>> g.search_rex(re.compile('Google')) <_sre.SRE_Match object at 0xb6b0a6b0> >>> g.search_rex(re.compile('Google\s+\w+', re.U)) <_sre.SRE_Match object at 0xb6b0a6e8> >>> g.search_rex(re.compile('Google\s+\w+', re.U)).group(0тАМ) u'Google Chrome' >>> g.assert_substring('  ') Traceback (most recent call last): File "", line 1, in File "grab/ext/text.py", line 62, in assert_substring if not self.search(anchor, byte=byte): File "grab/ext/text.py", line 37, in search raise GrabMisuseError('The anchor should be byte string in non-byte mode') grab.grab.GrabMisuseError: The anchor should be byte string in non-byte mode >>> g.assert_substring(u'  ') Traceback (most recent call last): File "", line 1, in File "grab/ext/text.py", line 63, in assert_substring raise DataNotFound('Substring not found: %s' % anchor) grab.grab.DataNotFound >>> g.drop_spaces('foo bar') Traceback (most recent call last): File "", line 1, in AttributeError: 'Grab' object has no attribute 'drop_spaces' >>> g.drop_space('foo bar') 'foobar' >>> g.normalize_space(' foo \n \t bar') 'foo bar' >>> g.find_number('12    ') '12' 


DOM рдЯреНрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ (Grab.ext.lxml рдПрдХреНрд╕рдЯреЗрдВрд╢рди)


рд╣рдо рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рджреГрд╖реНрдЯрд┐рдХреЛрдгред рдЕрджреНрднреБрдд lxml рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдЧреНрд░реИрдм рдЖрдкрдХреЛ рдбреЗрдЯрд╛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП xpath рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рджреЗрддрд╛ рд╣реИред рдпрджрд┐ рдмрд╣реБрдд рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ: `рдЯреНрд░реА` рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдЖрдк DOM рдЯреНрд░реА рдХреЛ рдПрд▓реАрдореЗрдВрдЯрдЯреНрд░реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рдПрдХреНрд╕реЗрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкреЗрдбрд╝ рдХреЛ lxml рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдк рджреЛ рдХреНрд╡реЗрд░реА рднрд╛рд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ DOM рдЯреНрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: xpath рдФрд░ cssред

Xpath рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ:

рдпрджрд┐ рддрддреНрд╡ рдирд╣реАрдВ рдорд┐рд▓рд╛, рддреЛ рдлрд╝рдВрдХреНрд╢рдВрд╕ `xpath`,` xpath_text` рдФрд░ `xpath_number` рдПрдХ DataNotFound рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХ рджреЗрдВрдЧреЗред

рдлрд╝рдВрдХреНрд╢рди `css`,` css_list`, `css_text` рдФрд░` css_number` рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде, рддрд░реНрдХ рдПрдХ xpath рдкрде рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдПрдХ css рдЪрдпрдирдХрд░реНрддрд╛ред
 >>> g = Grab() >>> g.go('http://habrahabr.ru') >>> g.xpath('//h2/a[@class="topic"]').get('href') 'http://habrahabr.ru/blogs/qt_software/127555/' >>> print g.xpath_text('//h2/a[@class="topic"]')  Qt Creator 2.3.0тАМ >>> print g.css_text('h2 a.topic')  Qt Creator 2.3.0тАМ >>> print 'Comments:', g.css_number('.comments .all') Comments: 5 >>> from urlparse import urlsplit >>> print ', '.join(urlsplit(x.get('href')).netloc for x in g.css_list('.hentry a') if not 'habrahabr.ru' in x.get('href') and x.get('href').startswith('http:')) labs.qt.nokia.com, labs.qt.nokia.com, thisismynext.com, www.htc.com, www.htc.com, droider.ru, radikal.ru, www.gosuslugi.ru, bit.ly 


рдкреНрд░рдкрддреНрд░ (Grab.ext.lxml_form рдПрдХреНрд╕рдЯреЗрдВрд╢рди)


рдЬрдм рдореИрдВрдиреЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдлреЙрд░реНрдо рднрд░рдиреЗ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд▓рд╛рдЧреВ рдХреА, рддреЛ рдореБрдЭреЗ рдмрд╣реБрдд рдЦреБрд╢реА рд╣реБрдИред рдЖрдк рдкрд░ рднреА рдЦреБрд╢реА! рддреЛ, рд╡рд╣рд╛рдБ `set_input` рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реИрдВ - рдпрд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╛рдо,` set_input_by_id` - рдЖрдИрдбреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдореВрд▓реНрдп рд╕реЗ рдлрд╝реАрд▓реНрдб рднрд░рддрд╛ рд╣реИ, рдФрд░ `set_input_by_number` - рдмрд╕ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рдеред рдпреЗ рд╡рд┐рдзрд┐рдпрд╛рдБ рдПрдХ рдРрд╕реЗ рд░реВрдк рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреА рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рд╛рде рд╕реЗ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдорддреМрд░ рдкрд░ рдЧреНрд░реИрдм рдЦреБрдж рд╣реА рд╕рд╣реА рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд▓реЗрддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рдлреЙрд░реНрдо рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╣реИред рдпрджрд┐ рдлрд╝реЙрд░реНрдо рдПрдХ рд╣реИ - рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдХрдИ рд╣реИрдВ? рдЧреНрд░реИрдм рдЙрд╕ рдлреЙрд░реНрдо рдХреЛ рд▓реЗрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдХреНрд╖реЗрддреНрд░ рд╣реИрдВред рдХрд┐рд╕реА рдкреНрд░рдкрддреНрд░ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, `select_form` рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЖрдк рд╕рдмрдорд┐рдЯ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреВрд░реНрдг рдХрд┐рдП рдЧрдП рдлреЙрд░реНрдо рдХреЛ рдЬрдорд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкрдХрдбрд╝реЛ рдЦреБрдж рд╣реА рдЙрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЛрд╕реНрдЯ / рдЬреАрдИрдЯреА рдЕрдиреБрд░реЛрдз рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВрдЧреЗ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдордиреЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд╣реАрдВ рднрд░рд╛ рдерд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЫрд┐рдкреЗ рд╣реБрдП рдХреНрд╖реЗрддреНрд░), рдлреЙрд░реНрдо рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдФрд░ рдЕрдиреБрд░реЛрдз рд╡рд┐рдзрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВред рдЗрд╕рдореЗрдВ 'form_fields' рдкрджреНрдзрддрд┐ рднреА рд╣реИ рдЬреЛ рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рд╕рднреА рдлрд╝реАрд▓реНрдб рдФрд░ рдлрд╝реЙрд░реНрдо рдорд╛рди рд▓реМрдЯрд╛рдПрдЧреАред
 >>> g.go('http://ya.ru/') >>> g.set_input('text', u' ') >>> g.submit() >>> print ', '.join(x.get('href') for x in g.css_list('.b-serp-url__link')) http://gigporno.ru/, http://drochinehochu.ru/, http://porno.bllogs.ru/, http://www.pornoflv.net/, http://www.plombir.ru/, http://vuku.ru/, http://www.carol.ru/, http://www.Porno-Mama.ru/, http://kashtanka.com/, http://www.xvidon.ru/ 


рдкрд░рд┐рд╡рд╣рди


рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдЧреНрд░реИрдм рд╕рднреА рдиреЗрдЯрд╡рд░реНрдХ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП pycurl рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рд▓рд╛рдЧреВ рдХреА рдЬрд╛рддреА рд╣реИ рдФрд░ рдЖрдк urllib2 рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдкрд░рд┐рд╡рд╣рди рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрдиреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдХреЗрд╡рд▓ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ, рдЗрд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП :) urllib2 рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдкрд░ рдХрд╛рдо рдЪрд▓ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдзреАрд░реЗ-рдзреАрд░реЗ - рдореИрдВ pycurl рд╕реЗ 100% рд╕рдВрддреБрд╖реНрдЯ рд╣реВрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ pycurl рдФрд░ urllib2 рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреНрд╖рдорддрд╛рдУрдВ рдореЗрдВ рд╕рдорд╛рди рд╣реЛрдВрдЧреЗ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ urllib2 SOCKS рдкреНрд░реЙрдХреНрд╕реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реИред рдЗрд╕ рдЖрд▓реЗрдЦ рдореЗрдВ рд╕рднреА рдЙрджрд╛рд╣рд░рдг pycurl рдкрд░рд┐рд╡рд╣рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕рдХреНрд╖рдо рд╣реИред
 >>> g = Grab() >>> g.curl <pycurl.Curl object at 0x9d4ba04> >>> g.extensions [<grab.ext.pycurl.Extension object at 0xb749056c>, <grab.ext.lxml.Extension object at 0xb749046c>, <grab.ext.lxml_form.Extension object at 0xb6de136c>, <grab.ext.django.Extension object at 0xb6a7e0ac>] 


рд╣рдереМрдбрд╝рд╛ рдореЛрдб


рдпрд╣ рдореЛрдб рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕рдХреНрд╖рдо рд╣реИред рдЧреНрд░реИрдм рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдордпрдмрд╛рд╣реНрдп рд╣реИред рд╣рдереМрдбрд╝рд╛ рдореЛрдб рдореЗрдВ, рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЧреНрд░реИрдм рддреБрд░рдВрдд рдПрдХ рдЕрдкрд╡рд╛рдж рдирд╣реАрдВ рдлреЗрдВрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдмрдврд╝рддреЗ рд╕рдордп рдХреЗ рд╕рд╛рде рдХрдИ рдмрд╛рд░ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдореЛрдб рдЖрдкрдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреА рд╕реНрдерд┐рд░рддрд╛ рдХреЛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд░реВрдк рд╕реЗ рдмрдврд╝рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЪреИрдирд▓ рдореЗрдВ рд╕рд╛рдЗрдЯреЛрдВ рдпрд╛ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рдХрд╛рдо рдореЗрдВ рд╕реВрдХреНрд╖реНрдо рдард╣рд░рд╛рд╡ рдХрд╛ рд╕рд╛рдордирд╛ рдЕрдХреНрд╕рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореЛрдб рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, 'рд╣рдереМрдбрд╝рд╛_рдореЛрдб' рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреА рд╕рдВрдЦреНрдпрд╛ рдФрд░ рд▓рдВрдмрд╛рдИ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, 'рд╣рдереМрдбрд╝рд╛_ рдЯрд╛рдЗрдордЖрдЙрдЯ' рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдЬреЛрдбрд╝реЗ рдХреА рдПрдХ рд╕реВрдЪреА рдкрд╛рд░рд┐рдд рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП: рдкрд╣рд▓рд╛ рдирдВрдмрд░ рд╕рд░реНрд╡рд░ рд╕реЙрдХреЗрдЯ рд╕реЗ рдХрдиреЗрдХреНрдЯ рд╣реЛрдиреЗ рдХрд╛ рд╕рдордп рд╣реИ, рджреВрд╕рд░рд╛ рдирдВрдмрд░ рдСрдкрд░реЗрд╢рди рд╕рд╣рд┐рдд рдкреВрд░реА рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдордЖрдЙрдЯ рд╣реИред рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдорд┐рд▓ рд░рд╣реА рд╣реИред
 >>> import logging >>> logging.basicConfig(level=logging.DEBUG) >>> g = Grab() >>> g.setup(hammer_mode=True, hammer_timeouts=((1, 1), (2, 2), (30, 30))) >>> URL = 'http://download.wikimedia.org/enwiki/20110803/enwiki-20110803-stub-articles5.xml.gz' >>> g.go(URL, method='head') DEBUG:grab:[01] HEAD http://download.wikimedia.org/enwiki/20110803/enwiki-20110803-stub-articles5.xml.gz >>> print 'File size: %d Mb' % (int(g.response.headers['Content-Length']) / (1024 * 1024)) File size: 3 Mb >>> g.go(URL, method='get') DEBUG:grab:[02] GET http://download.wikimedia.org/enwiki/20110803/enwiki-20110803-stub-articles5.xml.gz DEBUG:grab:Trying another timeouts. Connect: 2 sec., total: 2 sec. DEBUG:grab:[03] GET http://download.wikimedia.org/enwiki/20110803/enwiki-20110803-stub-articles5.xml.gz DEBUG:grab:Trying another timeouts. Connect: 30 sec., total: 30 sec. DEBUG:grab:[04] GET http://download.wikimedia.org/enwiki/20110803/enwiki-20110803-stub-articles5.xml.gz >>> print 'Downloaded: %d Mb' % (len(g.response.body) / (1024 * 1024)) Downloaded: 3 Mb 


Django рдПрдХреНрд╕рдЯреЗрдВрд╢рди (Grab.ext.django)


рд╣рд╛рдБ, рд╣рд╛рдБред рдРрд╕реА рдПрдХ рдЪреАрдЬ рд╣реИ :-) рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдореВрд╡реА рдореЙрдбрд▓ рд╣реИ рдЬрд┐рд╕рдореЗрдВ ImageField рдлрд╝реАрд▓реНрдб `рдЪрд┐рддреНрд░` рд╣реИред рдпрд╣рд╛рдВ рдЪрд┐рддреНрд░ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдореВрд╡реА рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рд╕рд╣реЗрдЬрдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
 >>> obj = Movie.objects.get(pk=797) >>> g = Grab() >>> g.go('http://img.yandex.net/i/www/logo.png') >>> obj.picture = g.django_file() >>> obj.save() 


рдЧреНрд░реИрдм рдореЗрдВ рдФрд░ рдХреНрдпрд╛ рд╣реИ?


рдЕрдиреНрдп рдЪрд┐рдкреНрд╕ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдбрд░ рд╣реИ рдХрд┐ рд▓реЗрдЦ рдмрд╣реБрдд рдмрдбрд╝рд╛ рд╣реЛрдЧрд╛ред рдЧреНрд░реИрдм рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛ рдореБрдЦреНрдп рдирд┐рдпрдо рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдХреЛрдб рджреЗрдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдкреНрд░рд▓реЗрдЦрди рдЕрднреА рднреА рдХрдордЬреЛрд░ рд╣реИ

рд╡рд┐рдХрд╛рд╕ рдХреА рдпреЛрдЬрдирд╛рдПрдБ


рдореИрдВ рдХрдИ рд╡рд░реНрд╖реЛрдВ рд╕реЗ рдЧреНрд░реИрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЬрд┐рд╕рдореЗрдВ рдЙрддреНрдкрд╛рджрди рд╕реНрдерд▓ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдЧреНрд░реАрдЧреЗрдЯрд░ рдореЗрдВ, рдЬрд╣рд╛рдВ рдЖрдк рдореЙрд╕реНрдХреЛ рдФрд░ рдЕрдиреНрдп рд╢рд╣рд░реЛрдВ рдореЗрдВ рдбрд┐рд╕реНрдХрд╛рдЙрдВрдЯ рдХреВрдкрди рдЦрд░реАрдж рд╕рдХрддреЗ рд╣реИрдВред 2011 рдореЗрдВ, рдореИрдВрдиреЗ рдкрд░реАрдХреНрд╖рдг рдФрд░ рджрд╕реНрддрд╛рд╡реЗрдЬ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред рд╢рд╛рдпрдж рдореИрдВ рдорд▓реНрдЯреАрдХрд▓рд░ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд▓рд┐рдЦреВрдВрдЧрд╛ред рдпреВрд░рд▓рд┐рдм рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ рдЦрддреНрдо рдХрд░рдирд╛ рднреА рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред

рдореИрдВ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдХреИрд╕реЗ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ? рдмрд╕ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдмрдЧреНрд░реЗрдкреЛрд░реНрдЯ рдФрд░ рдкреИрдЪ рднреЗрдЬреЗрдВред рдЖрдк рдореБрдЭрд╕реЗ рдкрд╛рд░реНрд╕рд░реНрд╕, рдЧреНрд░рдмрд░реНрд╕ , рд╕реВрдЪрдирд╛ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦрдиреЗ рдХрд╛ рднреА рдЖрджреЗрд╢ рджреЗ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рд╣рдбрд╝рдкрдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рддрд░рд╣ рдХреА рдЪреАрдЬреЗрдВ рд▓рд┐рдЦрддрд╛ рд╣реВрдВред

рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рднрдВрдбрд╛рд░: bitbucket.org/lorien/grab рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ pypi.python.org рд╕реЗ рднреА рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдорддреМрд░ рдкрд░ рднрдВрдбрд╛рд░ рдореЗрдВ рдХреЛрдб рддрд╛рдЬрд╝рд╛ рд╣реЛрддрд╛ рд╣реИред

UPD: рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╣реЙрд░реНрдирдмреАрдо рдХреЗ рд╕рднреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╡рд┐рдХрд▓реНрдк рджрд┐рдП рдЧрдПред рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ рд╕рд┐рд░ рд╕реЗ рдПрдХ рд╕реВрдЪреА + рдХреБрдЫ рдХреЗ рд╕рд╛рде рд╕рд╛рд░рд╛рдВрд╢рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрди рд╡реИрдЧрди рдФрд░ рдЫреЛрдЯреЗ рдЯреНрд░реЙрд▓реА рдХреЗ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рд░ рдПрди-рд╡реЗрдВ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдПрдХ рджрд┐рди рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдмрд╛рдЗрдХ рддрдп рдХрд░рддрд╛ рд╣реИ:


UPD2: рдХреГрдкрдпрд╛ рдЕрдкрдиреЗ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ Google рд╕рдореВрд╣ рдХреЛ рд▓рд┐рдЦреЗрдВ: group.google.com/group/python-grab/ рдЕрдиреНрдп рд╣рдбрд╝рдкрдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдкреНрд░рд╢реНрдиреЛрдВ рдФрд░ рдЙрддреНрддрд░реЛрдВ рд╕реЗ рдЦреБрдж рдХреЛ рдкрд░рд┐рдЪрд┐рдд рдХрд░рд╛рдирд╛ рд╕рд╣рд╛рдпрдХ рд╣реЛрдЧрд╛ред

UPD3: рдЕрдк-рдЯреВ-рдбреЗрдЯ рдкреНрд░рд▓реЗрдЦрди docs.grablib.org/ рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ

UPD4: рд╡рд░реНрддрдорд╛рди рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реНрдерд▓: Grablib.org

UPD5: рд▓реЗрдЦ рдореЗрдВ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдирд┐рд╢реНрдЪрд┐рдд рдЙрджрд╛рд╣рд░рдгред рдЕрдЧрд▓реЗ рдЙрдиреНрдирдпрди рдХреЗ рдмрд╛рдж, рд╣реЗрдмреНрд░рд╛рд╣реНрдм рдиреЗ рдЙрди рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдкреБрд░рд╛рдиреЗ рд▓реЗрдЦреЛрдВ рдореЗрдВ рдХреЛрдб рдХреЗ рдкреНрд░рд╛рд░реВрдкрдг рдХреЛ рд╕рд╣реА рдХрд░рдирд╛ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдЬрд┐рди рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдореБрдЭреЗ рд╕рдордЭ рдирд╣реАрдВ рдЖрдпрд╛ рдФрд░ рдпрд╣ рд╣рд░ рдЬрдЧрд╣ рдЪрд▓рд╛ рдЧрдпрд╛ред рд▓реЗрдЦ рдХреЛ рд╕рд╣реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд▓реЗрдХреНрд╕реА рдорд╛рдЬрд╝рд╛рдиреЛрд╡ рдХрд╛ рдзрдиреНрдпрд╡рд╛рджред рд╡рд╣ рднреА рд╣рдмрд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдирд┐рдордВрддреНрд░рдг рд╣реИ, рддреЛ рдЙрд╕рдХрд╛ рдореЗрд▓: egocentrist@me.com

Source: https://habr.com/ru/post/In127584/


All Articles