python爬虫能爬取什么_Python爬虫入门:爬取pixiv

终于想开始爬自己想爬的网站了。于是就试着爬P站试试手。

一开始以为不用登陆,就直接去爬图片了。

后来发现是需要登录的,但是不会只好去学模拟登陆。

然后还要去获取我们登陆时候需要的data。点住上面的presevelog,找到登陆的网址,点开查看Form Data就可以知道我们post的时候的data需要什么了。这里可以看到有个postkey,多试几次可以发现这个是变化的,即我们要去捕获它,而不能直接输入。

于是退回到登陆界面,F12查看源码,发现有一个postkey,那么我们就可以写一个东西去捕获它,然后把它放到我们post的data里面。

这里给出登陆界面需要的代码:

1 def __init__(self):2 self.base_url = 'https://accounts.pixiv.net/login?lang=zh&source=pc&view_type=page&ref=wwwtop_accounts_index'

3 self.login_url = 'https://accounts.pixiv.net/api/login?lang=zh'

4 self.target_url = 'http://www.pixiv.net/search.php?'\5 'word=%E5%9B%9B%E6%9C%88%E3%81%AF%E5%90%9B%E3%81%AE%E5%98%98&order=date_d&p='

6 self.main_url = 'http://www.pixiv.net'

7 #headers只要这两个就可以了,之前加了太多其他的反而爬不上

8 self.headers ={9 'Referer': 'https://accounts.pixiv.net/login?lang=zh&source=pc&view_type=page&ref=wwwtop_accounts_index',10 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)'

11 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'

12 }13 self.pixiv_id = 'userid'

14 self.password = '*****'

15 self.post_key =[]16 self.return_to = 'http://www.pixiv.net/'

17 self.load_path = 'D:\psdcode\Python\pixiv_pic'

18 self.ip_list =[]19

20 deflogin(self):21 post_key_html = se.get(self.base_url, headers=self.headers).text22 post_key_soup = BeautifulSoup(post_key_html, 'lxml')23 self.post_key = post_key_soup.find('input')['value']24 #上面是去捕获postkey

25 data ={26 'pixiv_id': self.pixiv_id,27 'password': self.password,28 'return_to': self.return_to,29 'post_key': self.post_key30 }31 se.post(self.login_url, data=data, headers=self.headers)

愉快地解决完登陆问题之后,就可以开始爬图片啦。

进入target_url:上面的目标网址。

点击目标的位置

点开ul这个标签,发现图片全部都是在

这里面的,因为我们要爬大一点的图(爬个小图有什么用啊!),所以还要进入一层第一个链接的网址去获取大图,我们可以发现我们只要在main_url((http://www.pixiv.net)),再加上第一个href,就可以跑到图片所在的网址了,于是我们先跳转到图片网址看看怎么提取图片。

发现图片就躺在这里了,而且连标题都有,直接方便了我们存图的名字了。于是我们就可以直接去提取图片了。

注意我们在请求获取图片的时候要加一个referer,否则会403的。referer的找法就和上面一样。

1 defget_img(self, html, page_num):2 li_soup = BeautifulSoup(html, 'lxml') #传入第page_num页的html

3 li_list = li_soup.find_all('li', attrs={'class', 'image-item'}) #找到li所在位置

4 #print('get_list succeed')

5 #print(li_list)

6 for li inli_list:7 href = li.find('a')['href'] #直接提取第一个href

8 #print('get_href succeed')

9 #print(href)

10 jump_to_url = self.main_url + href #跳转到目标的url

11 #print('get_jump_to_url succeed')

12 jump_to_html = self.get_html(jump_to_url, 3).text #获取图片的html

13 #print('get_jump_to_html succeed')

14

15 img_soup = BeautifulSoup(jump_to_html, 'lxml')16 img_info = img_soup.find('div', attrs={'class', 'works_display'})\17 .find('div', attrs={'class', '_layout-thumbnail ui-modal-trigger'})18 #找到目标位置的信息

19 if img_info is None: #有些找不到url,如果不continue会报错

20 continue

21 self.download_img(img_info, jump_to_url, page_num) #去下载这个图片

22

23 defdownload_img(self, img_info, href, page_num):24 title = img_info.find('img')['alt'] #提取标题

25 src = img_info.find('img')['src'] #提取图片位置

26 src_headers =self.headers27 src_headers['Referer'] = href #增加一个referer,否则会403,referer就像上面登陆一样找

28 try:29 html = requests.get(src, headers=src_headers)30 img =html.content31 except: #有时候会发生错误导致不能获取图片.直接跳过这张图吧

32 print('获取该图片失败')33 return False

接下来轮到下载图片了。这个之前还不怎么会,临时学了一下。

首先是创建文件夹,我这里是每一页就开一个文件夹。

1 defmkdir(self, path):2 path =path.strip()3 is_exist =os.path.exists(os.path.join(self.load_path, path))4 if notis_exist:5 print('创建一个名字为' + path + '的文件夹')6 os.makedirs(os.path.join(self.load_path, path))7 os.chdir(os.path.join(self.load_path, path))8 returnTrue9 else:10 print('名字为' + path + '的文件夹已经存在')11 os.chdir(os.path.join(self.load_path, path))12 return False

1 defdownload_img(self, img_info, href, page_num):2 title = img_info.find('img')['alt'] #提取标题

3 src = img_info.find('img')['src'] #提取图片位置

4 src_headers =self.headers5 src_headers['Referer'] = href #增加一个referer,否则会403,referer就像上面登陆一样找

6 try:7 html = requests.get(src, headers=src_headers)8 img =html.content9 except: #有时候会发生错误导致不能获取图片.直接跳过这张图吧

10 print('获取该图片失败')11 returnFalse12

13 title = title.replace('?', '_').replace('/', '_').replace('\\', '_').replace('*', '_').replace('|', '_')\14 .replace('>', '_').replace('

16

17 if os.path.exists(os.path.join(self.load_path, str(page_num), title + '.jpg')):18 for i in range(1, 100):19 if not os.path.exists(os.path.join(self.load_path, str(page_num), title + str(i) + '.jpg')):20 title = title +str(i)21 break

22 #如果重名了,就加上一个数字

23 print('正在保存名字为:' + title + '的图片')24 with open(title + '.jpg', 'ab') as f:25 f.write(img)26 print('保存该图片完毕')

这样我们的大体工作就做完了。剩下的是写一个work函数让它开始跑。

1 defwork(self):2 self.login()3 for page_num in range(1, 51): #太多页了,只跑50页

4 path = str(page_num) #每一页就开一个文件夹

5 self.mkdir(path) #创建文件夹

6 #print(self.target_url + str(page_num))

7 now_html = self.get_html(self.target_url + str(page_num), 3) #获取页码

8 self.get_img(now_html.text, page_num) #获取图片

9 print('第 {page} 页保存完毕'.format(page=page_num))10 time.sleep(2) #防止太快被反

启动!

大概跑了10页之后,会弹出一大堆信息什么requests不行怎么的。问了下别人应该是被反爬了。

于是去搜了一下资料,http://cuiqingcai.com/3256.html,照着他那样写了使用代理的东西。(基本所有东西都在这学的)。

于是第一个小爬虫就好了。不过代理的东西还没怎么懂,到时候看看,50页爬了两个多钟。

对了。可能网站的源代码会有改动的。因为我吃完饭后用吃饭前的代码继续工作的时候出错了,然后要仔细观察重新干。

1 #-*- coding:utf-8 -*-

2 importrequests3 from bs4 importBeautifulSoup4 importos5 importtime6 importre7 importrandom8

9 se =requests.session()10

11

12 classPixiv():13

14 def __init__(self):15 self.base_url = 'https://accounts.pixiv.net/login?lang=zh&source=pc&view_type=page&ref=wwwtop_accounts_index'

16 self.login_url = 'https://accounts.pixiv.net/api/login?lang=zh'

17 self.target_url = 'http://www.pixiv.net/search.php?'\18 'word=%E5%9B%9B%E6%9C%88%E3%81%AF%E5%90%9B%E3%81%AE%E5%98%98&order=date_d&p='

19 self.main_url = 'http://www.pixiv.net'

20 #headers只要这两个就可以了,之前加了太多其他的反而爬不上

21 self.headers ={22 'Referer': 'https://accounts.pixiv.net/login?lang=zh&source=pc&view_type=page&ref=wwwtop_accounts_index',23 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)'

24 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'

25 }26 self.pixiv_id = 'userid'

27 self.password = '*****'

28 self.post_key =[]29 self.return_to = 'http://www.pixiv.net/'

30 self.load_path = 'D:\psdcode\Python\pixiv_pic'

31 self.ip_list =[]32

33 deflogin(self):34 post_key_html = se.get(self.base_url, headers=self.headers).text35 post_key_soup = BeautifulSoup(post_key_html, 'lxml')36 self.post_key = post_key_soup.find('input')['value']37 #上面是去捕获postkey

38 data ={39 'pixiv_id': self.pixiv_id,40 'password': self.password,41 'return_to': self.return_to,42 'post_key': self.post_key43 }44 se.post(self.login_url, data=data, headers=self.headers)45

46 defget_proxy(self):47 html = requests.get('http://haoip.cc/tiqu.htm')48 ip_list_temp = re.findall(r'r/>(.*?)

54 '''会被反爬,改成使用代理55 def get_tml(self, url):56 response = se.get(url, headers=self.headers)57 return response58 '''

59 def get_html(self, url, timeout, proxy=None, num_entries=5):60 if proxy isNone:61 try:62 return se.get(url, headers=self.headers, timeout=timeout)63 except:64 if num_entries >0:65 print('获取网页出错,5秒后将会重新获取倒数第', num_entries, '次')66 time.sleep(5)67 return self.get_html(url, timeout, num_entries = num_entries - 1)68 else:69 print('开始使用代理')70 time.sleep(5)71 ip = ''.join(str(random.choice(self.ip_list))).strip()72 now_proxy = {'http': ip}73 return self.get_html(url, timeout, proxy =now_proxy)74 else:75 try:76 return se.get(url, headers=self.headers, proxies=proxy, timeout=timeout)77 except:78 if num_entries >0:79 print('正在更换代理,5秒后将会重新获取第', num_entries, '次')80 time.sleep(5)81 ip = ''.join(str(random.choice(self.ip_list))).strip()82 now_proxy = {'http': ip}83 return self.get_html(url, timeout, proxy = now_proxy, num_entries = num_entries - 1)84 else:85 print('使用代理失败,取消使用代理')86 returnself.get_html(url, timeout)87

88 defget_img(self, html, page_num):89 li_soup = BeautifulSoup(html, 'lxml') #传入第page_num页的html

90 li_list = li_soup.find_all('li', attrs={'class', 'image-item'}) #找到li所在位置

91 #print('get_list succeed')

92 #print(li_list)

93 for li inli_list:94 href = li.find('a')['href'] #直接提取第一个href

95 #print('get_href succeed')

96 #print(href)

97 jump_to_url = self.main_url + href #跳转到目标的url

98 #print('get_jump_to_url succeed')

99 jump_to_html = self.get_html(jump_to_url, 3).text #获取图片的html

100 #print('get_jump_to_html succeed')

101

102 img_soup = BeautifulSoup(jump_to_html, 'lxml')103 img_info = img_soup.find('div', attrs={'class', 'works_display'})\104 .find('div', attrs={'class', '_layout-thumbnail ui-modal-trigger'})105 #找到目标位置的信息

106 if img_info is None: #有些找不到url,如果不continue会报错

107 continue

108 self.download_img(img_info, jump_to_url, page_num) #去下载这个图片

109

110 defdownload_img(self, img_info, href, page_num):111 title = img_info.find('img')['alt'] #提取标题

112 src = img_info.find('img')['src'] #提取图片位置

113 src_headers =self.headers114 src_headers['Referer'] = href #增加一个referer,否则会403,referer就像上面登陆一样找

115 try:116 html = requests.get(src, headers=src_headers)117 img =html.content118 except: #有时候会发生错误导致不能获取图片.直接跳过这张图吧

119 print('获取该图片失败')120 returnFalse121

122 title = title.replace('?', '_').replace('/', '_').replace('\\', '_').replace('*', '_').replace('|', '_')\123 .replace('>', '_').replace('

125

126 if os.path.exists(os.path.join(self.load_path, str(page_num), title + '.jpg')):127 for i in range(1, 100):128 if not os.path.exists(os.path.join(self.load_path, str(page_num), title + str(i) + '.jpg')):129 title = title +str(i)130 break

131 #如果重名了,就加上一个数字

132 print('正在保存名字为:' + title + '的图片')133 with open(title + '.jpg', 'ab') as f: #图片要用b

134 f.write(img)135 print('保存该图片完毕')136

137 defmkdir(self, path):138 path =path.strip()139 is_exist =os.path.exists(os.path.join(self.load_path, path))140 if notis_exist:141 print('创建一个名字为' + path + '的文件夹')142 os.makedirs(os.path.join(self.load_path, path))143 os.chdir(os.path.join(self.load_path, path))144 returnTrue145 else:146 print('名字为' + path + '的文件夹已经存在')147 os.chdir(os.path.join(self.load_path, path))148 returnFalse149

150 defwork(self):151 self.login()152 for page_num in range(1, 51): #太多页了,只跑50页

153 path = str(page_num) #每一页就开一个文件夹

154 self.mkdir(path) #创建文件夹

155 #print(self.target_url + str(page_num))

156 now_html = self.get_html(self.target_url + str(page_num), 3) #获取页码

157 self.get_img(now_html.text, page_num) #获取图片

158 print('第 {page} 页保存完毕'.format(page=page_num))159 time.sleep(2) #防止太快被反

160

161

162 pixiv =Pixiv()163 pixiv.work()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值